commit a4d98eea5071250c1c610de2df7f43ab57b208f0 Author: Conan Scott Date: Tue Dec 9 19:34:54 2025 +1100 Initial commit diff --git a/Chart.lock b/Chart.lock new file mode 100644 index 0000000..83bbdba --- /dev/null +++ b/Chart.lock @@ -0,0 +1,27 @@ +dependencies: +- name: openebs-crds + repository: "" + version: 4.4.0 +- name: loki + repository: https://grafana.github.io/helm-charts + version: 6.29.0 +- name: alloy + repository: https://grafana.github.io/helm-charts + version: 1.0.1 +- name: localpv-provisioner + repository: https://openebs.github.io/dynamic-localpv-provisioner + version: 4.4.0 +- name: zfs-localpv + repository: https://openebs.github.io/zfs-localpv + version: 2.9.0 +- name: lvm-localpv + repository: https://openebs.github.io/lvm-localpv + version: 1.8.0 +- name: rawfile-localpv + repository: https://openebs.github.io/rawfile-localpv + version: 0.12.0 +- name: mayastor + repository: https://openebs.github.io/mayastor-extensions + version: 2.10.0 +digest: sha256:e4e736f6fcbfa61a20c60c1ee90249fb6201bc6828925a83203ef08acaf0b9fd +generated: "2025-11-21T15:17:15.701358471Z" diff --git a/Chart.yaml b/Chart.yaml new file mode 100644 index 0000000..af5c55c --- /dev/null +++ b/Chart.yaml @@ -0,0 +1,131 @@ +annotations: + helm.sh/images: | + - name: alloy + image: docker.io/grafana/alloy:v1.8.1 + - name: loki + image: docker.io/grafana/loki:3.4.2 + - name: k8s-sidecar + image: docker.io/kiwigrid/k8s-sidecar:1.30.2 + - name: nats + image: docker.io/nats:2.9.17-alpine + - name: nats-box + image: docker.io/natsio/nats-box:0.13.8 + - name: nats-server-config-reloader + image: docker.io/natsio/nats-server-config-reloader:0.10.1 + - name: prometheus-nats-exporter + image: docker.io/natsio/prometheus-nats-exporter:0.11.0 + - name: alpine-bash + image: docker.io/openebs/alpine-bash:4.3.0 + - name: alpine-sh + image: docker.io/openebs/alpine-sh:4.3.0 + - name: etcd + image: docker.io/openebs/etcd:3.6.4-debian-12-r0 + - name: kubectl + image: docker.io/openebs/kubectl:1.25.15 + - name: linux-utils + image: docker.io/openebs/linux-utils:4.3.0 + - name: lvm-driver + image: docker.io/openebs/lvm-driver:1.8.0 + - name: mayastor-agent-core + image: docker.io/openebs/mayastor-agent-core:v2.10.0 + - name: mayastor-agent-ha-cluster + image: docker.io/openebs/mayastor-agent-ha-cluster:v2.10.0 + - name: mayastor-agent-ha-node + image: docker.io/openebs/mayastor-agent-ha-node:v2.10.0 + - name: mayastor-api-rest + image: docker.io/openebs/mayastor-api-rest:v2.10.0 + - name: mayastor-csi-controller + image: docker.io/openebs/mayastor-csi-controller:v2.10.0 + - name: mayastor-csi-node + image: docker.io/openebs/mayastor-csi-node:v2.10.0 + - name: mayastor-io-engine + image: docker.io/openebs/mayastor-io-engine:v2.10.0 + - name: mayastor-metrics-exporter-io-engine + image: docker.io/openebs/mayastor-metrics-exporter-io-engine:v2.10.0 + - name: mayastor-obs-callhome-stats + image: docker.io/openebs/mayastor-obs-callhome-stats:v2.10.0 + - name: mayastor-obs-callhome + image: docker.io/openebs/mayastor-obs-callhome:v2.10.0 + - name: mayastor-operator-diskpool + image: docker.io/openebs/mayastor-operator-diskpool:v2.10.0 + - name: provisioner-localpv + image: docker.io/openebs/provisioner-localpv:4.4.0 + - name: rawfile-localpv + image: docker.io/openebs/rawfile-localpv:v0.12.0 + - name: zfs-driver + image: docker.io/openebs/zfs-driver:2.9.0 + - name: mc + image: quay.io/minio/mc:RELEASE.2024-11-21T17-21-54Z + - name: minio + image: quay.io/minio/minio:RELEASE.2024-12-18T13-15-44Z + - name: prometheus-config-reloader + image: quay.io/prometheus-operator/prometheus-config-reloader:v0.81.0 + - name: csi-attacher + image: registry.k8s.io/sig-storage/csi-attacher:v4.8.1 + - name: csi-node-driver-registrar + image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.13.0 + - name: csi-provisioner + image: registry.k8s.io/sig-storage/csi-provisioner:v5.2.0 + - name: csi-resizer + image: registry.k8s.io/sig-storage/csi-resizer:v1.11.2 + - name: csi-resizer + image: registry.k8s.io/sig-storage/csi-resizer:v1.13.2 + - name: csi-snapshotter + image: registry.k8s.io/sig-storage/csi-snapshotter:v7.0.0 + - name: csi-snapshotter + image: registry.k8s.io/sig-storage/csi-snapshotter:v8.2.0 + - name: csi-snapshotter + image: registry.k8s.io/sig-storage/csi-snapshotter:v8.2.1 + - name: snapshot-controller + image: registry.k8s.io/sig-storage/snapshot-controller:v7.0.0 + - name: snapshot-controller + image: registry.k8s.io/sig-storage/snapshot-controller:v8.2.0 + - name: snapshot-controller + image: registry.k8s.io/sig-storage/snapshot-controller:v8.2.1 +apiVersion: v2 +appVersion: 4.4.0 +dependencies: +- name: openebs-crds + repository: "" + version: 4.4.0 +- condition: loki.enabled + name: loki + repository: https://grafana.github.io/helm-charts + version: 6.29.0 +- condition: alloy.enabled + name: alloy + repository: https://grafana.github.io/helm-charts + version: 1.0.1 +- name: localpv-provisioner + repository: https://openebs.github.io/dynamic-localpv-provisioner + version: 4.4.0 +- condition: engines.local.zfs.enabled + name: zfs-localpv + repository: https://openebs.github.io/zfs-localpv + version: 2.9.0 +- condition: engines.local.lvm.enabled + name: lvm-localpv + repository: https://openebs.github.io/lvm-localpv + version: 1.8.0 +- condition: engines.local.rawfile.enabled + name: rawfile-localpv + repository: https://openebs.github.io/rawfile-localpv + version: 0.12.0 +- condition: engines.replicated.mayastor.enabled + name: mayastor + repository: https://openebs.github.io/mayastor-extensions + version: 2.10.0 +description: Containerized Attached Storage for Kubernetes +home: https://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/HEAD/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- local-storage +- NVMe +- storage +- kubernetes +name: openebs +sources: +- https://github.com/openebs/openebs +version: 4.4.0 diff --git a/README.md b/README.md new file mode 100644 index 0000000..11583e1 --- /dev/null +++ b/README.md @@ -0,0 +1,129 @@ +# OpenEBS Helm Repository + +OpenEBS Logo + +[OpenEBS](https://openebs.io) helps Developers and Platform SREs easily deploy Kubernetes Stateful Workloads that require fast and highly reliable container attached storage. OpenEBS can be deployed on any Kubernetes cluster - either in cloud, on-premise (virtual or bare metal) or developer system (minikube). + +OpenEBS Data Engines and Control Plane are implemented as micro-services, deployed as containers and orchestrated by Kubernetes itself. An added advantage of being a completely Kubernetes native solution is that administrators and developers can interact and manage OpenEBS using all the wonderful tooling that is available for Kubernetes like kubectl, Helm, Prometheus, Grafana, etc. + +OpenEBS turns any storage available on the Kubernetes worker nodes into local or distributed Kubernetes Persistent Volumes. + +#### Local PV + +Local Volumes are accessible only from a single node in the cluster. Pods using Local Volume have to be scheduled on the node where volume is provisioned. Local Volumes are typically preferred for distributed workloads like Cassandra, MongoDB, Elastic, etc that are distributed in nature and have high availability built into them. Depending on the type of storage attached to the Kubernetes worker, OpenEBS offers different flavors of Local PV - Hostpath, LVM and ZFS. + +#### Replicated PV + +Replicated Volumes as the name suggests, are those that have their data synchronously replicated to multiple nodes. Volumes can sustain node failures. The replication also can be setup across availability zones helping applications move across availability zones. OpenEBS offers Replicated PV Mayastor as an replicated storage solution, which provides high availability and high performance. + +## Documentation and user guides + +OpenEBS can run on any Kubernetes 1.23+ cluster in a matter of minutes. See the [Quickstart Guide to OpenEBS](https://openebs.io/docs/quickstart-guide/installation) for detailed instructions. + +## Getting started + +### How to customize OpenEBS Helm chart? + +OpenEBS Helm chart is a unified Helm chart that pulls together engine specific charts. The engine charts are included as [dependencies](https://github.com/openebs/openebs/tree/HEAD/charts/Chart.yaml). + +```bash +openebs +├── (default) Local PV HostPath +├── (default) Local PV LVM +├── (default) Local PV ZFS +└── (default) Replicated PV Mayastor +``` + +### Prerequisites + +- [Local PV Hostpath Prerequisites](https://openebs.io/docs/user-guides/local-storage-user-guide/local-pv-hostpath/hostpath-installation#prerequisites) +- [Local PV LVM Prerequisites](https://openebs.io/docs/user-guides/local-storage-user-guide/local-pv-lvm/lvm-installation#prerequisites) +- [Local PV ZFS Prerequisites](https://openebs.io/docs/user-guides/local-storage-user-guide/local-pv-zfs/zfs-installation#prerequisites) +- [Replicated PV Mayastor Prerequisites](https://openebs.io/docs/user-guides/replicated-storage-user-guide/replicated-pv-mayastor/rs-installation#prerequisites) + +### Setup Helm Repository + +Before installing OpenEBS Helm chart, the [OpenEBS Helm repository](https://openebs.github.io/openebs) needs to be added to the Helm client. + +#### Setup Helm repository + +```bash +helm repo add openebs https://openebs.github.io/openebs +helm repo update +``` + +#### Install OpenEBS Helm chart with default values. + +```bash +helm install openebs --namespace openebs openebs/openebs --create-namespace +``` + +The above commands will install OpenEBS LocalPV Hostpath, OpenEBS LocalPV LVM, OpenEBS LocalPV ZFS and OpenEBS Mayastor components in openebs namespace with chart name as openebs. + +Replicated PV Mayastor can be excluded during the installation with the following command: + +```bash +helm install openebs --namespace openebs openebs/openebs --set engines.replicated.mayastor.enabled=false --create-namespace +``` + +To view the chart and get the following output. + +```bash +helm ls -n openebs + +NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION +openebs openebs 1 2025-01-10 09:13:00.903321318 +0000 UTC deployed openebs-4.4.0 4.4.0 +``` + +As a next step [verify the installation](https://openebs.io/docs/quickstart-guide/installation#verifying-openebs-installation) and do the [post installation](https://openebs.io/docs/quickstart-guide/installation#post-installation-considerations) steps. + +For more details on customizing and installing OpenEBS please see the [chart values](https://github.com/openebs/openebs/tree/HEAD/charts/README.md). + +### To uninstall/delete instance with release name + +```bash +helm ls --all +helm delete `` -n `` +``` + +> **Tip**: Prior to deleting the Helm chart, make sure all the storage volumes and pools are deleted. + +## Requirements + +| Repository | Name | Version | +|------------|------|---------| +| | openebs-crds | 4.4.0 | +| https://grafana.github.io/helm-charts | alloy | 1.0.1 | +| https://grafana.github.io/helm-charts | loki | 6.29.0 | +| https://openebs.github.io/dynamic-localpv-provisioner | localpv-provisioner | 4.4.0 | +| https://openebs.github.io/lvm-localpv | lvm-localpv | 1.8.0 | +| https://openebs.github.io/mayastor-extensions | mayastor | 2.10.0 | +| https://openebs.github.io/rawfile-localpv | rawfile-localpv | 0.12.0 | +| https://openebs.github.io/zfs-localpv | zfs-localpv | 2.9.0 | + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| lvm-localpv.crds.csi.volumeSnapshots.enabled | bool | `false` | | +| lvm-localpv.crds.lvmLocalPv.enabled | bool | `true` | | +| mayastor.alloy.enabled | bool | `false` | | +| mayastor.crds.enabled | bool | `false` | | +| mayastor.csi.node.initContainers.enabled | bool | `true` | | +| mayastor.etcd.clusterDomain | string | `"cluster.local"` | Kubernetes Cluster Domain | +| mayastor.localpv-provisioner.enabled | bool | `false` | | +| mayastor.loki.enabled | bool | `false` | | +| openebs-crds.csi.volumeSnapshots.enabled | bool | `true` | | +| openebs-crds.csi.volumeSnapshots.keep | bool | `true` | | +| preUpgradeHook.annotations."helm.sh/hook-delete-policy" | string | `"hook-succeeded,before-hook-creation"` | | +| preUpgradeHook.enabled | bool | `true` | Enable/Disable openebs pre-upgrade hook | +| preUpgradeHook.image.pullPolicy | string | `"IfNotPresent"` | The imagePullPolicy for the container | +| preUpgradeHook.image.registry | string | `"docker.io"` | The container image registry URL for the hook job | +| preUpgradeHook.image.repo | string | `"openebs/kubectl"` | The container repository for the hook job | +| preUpgradeHook.image.tag | string | `"1.25.15"` | The container image tag for the hook job | +| preUpgradeHook.imagePullSecrets | list | `[]` | Optional array of imagePullSecrets containing private registry credentials # Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ | +| preUpgradeHook.podLabels."openebs.io/logging" | string | `"true"` | | +| preUpgradeHook.tolerations | list | `[]` | Node tolerations for server scheduling to nodes with taints # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ # | +| rawfile-localpv.crds.csi.volumeSnapshots.enabled | bool | `false` | | +| zfs-localpv.crds.csi.volumeSnapshots.enabled | bool | `false` | | +| zfs-localpv.crds.zfsLocalPv.enabled | bool | `true` | | diff --git a/charts/alloy/.helmignore b/charts/alloy/.helmignore new file mode 100644 index 0000000..da2093f --- /dev/null +++ b/charts/alloy/.helmignore @@ -0,0 +1,29 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ + +# Don't package templates. +README.md.gotmpl + +# Don't packages the tests used for CI. +/tests/ diff --git a/charts/alloy/CHANGELOG.md b/charts/alloy/CHANGELOG.md new file mode 100644 index 0000000..1623c85 --- /dev/null +++ b/charts/alloy/CHANGELOG.md @@ -0,0 +1,245 @@ +# Changelog + +> _Contributors should read our [contributors guide][] for instructions on how +> to update the changelog._ + +This document contains a historical list of changes between releases. Only +changes that impact end-user behavior are listed; changes to documentation or +internal API changes are not present. + +Unreleased +---------- + +1.0.1 (2025-04-10) +---------- + +### Enhancements + +- Update to Grafana Alloy v1.8.1. (@dehaansa) + +- Update default configreloader resources to match what is set in prometheus-operator project (@dehaansa) + +- Add Vertical Pod Autoscaler support (@QuentinBisson) + +1.0.0 (2025-04-09) +---------- + +### Enhancements + +- Update version to `1.0.0`. This Helm chart is now covered with the [backward-compatibility](https://grafana.com/docs/alloy/latest/introduction/backward-compatibility/) policy. + +- Update to Grafana Alloy v1.8.0. (@thampiotr) + +0.12.6 (2025-04-03) +---------- +### Breaking changes + +- configReloader.customArgs are likely to break as the prometheus maintained config reloader does not have the same arguments as the previous image (@dehaansa) + +### Enhancements + +- Change configReloader from jimmydyson/configmap-reload to prometheus-operator/prometheus-config-reloader (@dehaansa) +- Update to Grafana Alloy v1.7.5. (@kimxogus) +- Add `checksum/config` pod annotation (@kimxogus) + +### Other changes + +- Fix typo in values.yaml documentation (@petewall) + +0.12.5 (2025-03-13) +---------- +### Enhancements + +- Update to Grafana Alloy v1.7.4. (@dehaansa) + +0.12.4 (2025-03-13) +---------- +### Enhancements + +- Update to Grafana Alloy v1.7.3. (@dehaansa) + +0.12.3 (2025-03-10) +---------- + +### Enhancements + +- Add support for adding livenessProbe to agent container (@slimes28) + +0.12.2 (2025-03-10) +---------- + +### Bug Fixes + +- Set resource namespace correctly (@shinebayar-g) + +### Enhancements + +- Add a new `automountServiceAccountToken` configuration value for `serviceAccount`. (@ptodev) +- Update to Grafana Alloy v1.7.2. (@thampiotr) + +0.12.1 (2025-02-26) +---------- + +### Enhancements + +- Update to Grafana Alloy v1.7.1. (@thampiotr) + +0.12.0 (2025-02-24) +---------- + +### Enhancements + +- Update to Grafana Alloy v1.7.0. (@thampiotr) + +0.11.0 (2025-01-23) +---------- + +### Enhancements + +- Update jimmidyson/configmap-reload to 0.14.0. (@petewall) +- Add the ability to deploy extra manifest files. (@dbluxo) + +0.10.1 (2024-12-03) +---------- + +### Enhancements + +- Update to Grafana Alloy v1.5.1. (@ptodev) + +0.10.0 (2024-11-13) +---------- + +### Enhancements + +- Add support for adding hostAliases to the Helm chart. (@duncan485) +- Update to Grafana Alloy v1.5.0. (@thampiotr) + +0.9.2 (2024-10-18) +------------------ + +### Enhancements + +- Update to Grafana Alloy v1.4.3. (@ptodev) + +0.9.1 (2024-10-04) +------------------ + +### Enhancements + +- Update to Grafana Alloy v1.4.2. (@ptodev) + +0.9.0 (2024-10-02) +------------------ + +### Enhancements + +- Add lifecyle hook to the Helm chart. (@etiennep) +- Add terminationGracePeriodSeconds setting to the Helm chart. (@etiennep) + +0.8.1 (2024-09-26) +------------------ + +### Enhancements + +- Update to Grafana Alloy v1.4.1. (@ptodev) + +0.8.0 (2024-09-25) +------------------ + +### Enhancements + +- Update to Grafana Alloy v1.4.0. (@ptodev) + +0.7.0 (2024-08-26) +------------------ + +### Enhancements + +- Add PodDisruptionBudget to the Helm chart. (@itspouya) + +0.6.1 (2024-08-23) +---------- + +### Enhancements + +- Add the ability to set --cluster.name in the Helm chart with alloy.clustering.name. (@petewall) +- Add the ability to set appProtocol in extraPorts to help OpenShift users to expose gRPC. (@clementduveau) + +### Other changes + +- Update helm chart to use v1.3.1. + +0.6.0 (2024-08-05) +------------------ + +### Other changes + +- Update helm chart to use v1.3.0. + +- Set `publishNotReadyAddresses` to `true` in the service spec for clustering to fix a bug where peers could not join on startup. (@wildum) + +0.5.1 (2023-07-11) +------------------ + +### Other changes + +- Update helm chart to use v1.2.1. + +0.5.0 (2024-07-08) +------------------ + +### Enhancements + +- Only utilize spec.internalTrafficPolicy in the Service if deploying to Kubernetes 1.26 or later. (@petewall) + +0.4.0 (2024-06-26) +------------------ + +### Enhancements + +- Update to Grafana Alloy v1.2.0. (@ptodev) + +0.3.2 (2024-05-30) +------------------ + +### Bugfixes + +- Update to Grafana Alloy v1.1.1. (@rfratto) + +0.3.1 (2024-05-22) +------------------ + +### Bugfixes + +- Fix clustering on instances running within Istio mesh by allowing to change the name of the clustering port + +0.3.0 (2024-05-14) +------------------ + +### Enhancements + +- Update to Grafana Alloy v1.1.0. (@rfratto) + +0.2.0 (2024-05-08) +------------------ + +### Other changes + +- Support all [Kubernetes recommended labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/) (@nlamirault) + +0.1.1 (2024-04-11) +------------------ + +### Other changes + +- Add missing Alloy icon to Chart.yaml. (@rfratto) + +0.1.0 (2024-04-09) +------------------ + +### Features + +- Introduce a Grafana Alloy Helm chart. The Grafana Alloy Helm chart is + backwards compatibile with the values.yaml from the `grafana-agent` Helm + chart. Review the Helm chart README for a description on how to migrate. + (@rfratto) diff --git a/charts/alloy/Chart.lock b/charts/alloy/Chart.lock new file mode 100644 index 0000000..b459e48 --- /dev/null +++ b/charts/alloy/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: crds + repository: "" + version: 0.0.0 +digest: sha256:1980431a3d80822fca2e67e9cf16ff7a7f8d1dc87deb9e44d50e85e3e8e33a81 +generated: "2025-04-11T09:30:48.378858526Z" diff --git a/charts/alloy/Chart.yaml b/charts/alloy/Chart.yaml new file mode 100644 index 0000000..e23ca6f --- /dev/null +++ b/charts/alloy/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 +appVersion: v1.8.1 +dependencies: +- condition: crds.create + name: crds + repository: "" + version: 0.0.0 +description: Grafana Alloy +icon: https://raw.githubusercontent.com/grafana/alloy/main/docs/sources/assets/alloy_icon_orange.svg +name: alloy +type: application +version: 1.0.1 diff --git a/charts/alloy/README.md b/charts/alloy/README.md new file mode 100644 index 0000000..7492392 --- /dev/null +++ b/charts/alloy/README.md @@ -0,0 +1,342 @@ +# Grafana Alloy Helm chart + +![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 1.0.1](https://img.shields.io/badge/Version-1.0.1-informational?style=flat-square) ![AppVersion: v1.8.1](https://img.shields.io/badge/AppVersion-v1.8.1-informational?style=flat-square) + +Helm chart for deploying [Grafana Alloy][] to Kubernetes. + +[Grafana Alloy]: https://grafana.com/docs/alloy/latest/ + +## Usage + +### Setup Grafana chart repository + +``` +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +### Install chart + +To install the chart with the release name my-release: + +`helm install my-release grafana/alloy` + +This chart installs one instance of Grafana Alloy into your Kubernetes cluster +using a specific Kubernetes controller. By default, DaemonSet is used. The +`controller.type` value can be used to change the controller to either a +StatefulSet or Deployment. + +Creating multiple installations of the Helm chart with different controllers is +useful if just using the default DaemonSet isn't sufficient. + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| alloy.clustering.enabled | bool | `false` | Deploy Alloy in a cluster to allow for load distribution. | +| alloy.clustering.name | string | `""` | Name for the Alloy cluster. Used for differentiating between clusters. | +| alloy.clustering.portName | string | `"http"` | Name for the port used for clustering, useful if running inside an Istio Mesh | +| alloy.configMap.content | string | `""` | Content to assign to the new ConfigMap. This is passed into `tpl` allowing for templating from values. | +| alloy.configMap.create | bool | `true` | Create a new ConfigMap for the config file. | +| alloy.configMap.key | string | `nil` | Key in ConfigMap to get config from. | +| alloy.configMap.name | string | `nil` | Name of existing ConfigMap to use. Used when create is false. | +| alloy.enableReporting | bool | `true` | Enables sending Grafana Labs anonymous usage stats to help improve Grafana Alloy. | +| alloy.envFrom | list | `[]` | Maps all the keys on a ConfigMap or Secret as environment variables. https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#envfromsource-v1-core | +| alloy.extraArgs | list | `[]` | Extra args to pass to `alloy run`: https://grafana.com/docs/alloy/latest/reference/cli/run/ | +| alloy.extraEnv | list | `[]` | Extra environment variables to pass to the Alloy container. | +| alloy.extraPorts | list | `[]` | Extra ports to expose on the Alloy container. | +| alloy.hostAliases | list | `[]` | Host aliases to add to the Alloy container. | +| alloy.lifecycle | object | `{}` | Set lifecycle hooks for the Grafana Alloy container. | +| alloy.listenAddr | string | `"0.0.0.0"` | Address to listen for traffic on. 0.0.0.0 exposes the UI to other containers. | +| alloy.listenPort | int | `12345` | Port to listen for traffic on. | +| alloy.listenScheme | string | `"HTTP"` | Scheme is needed for readiness probes. If enabling tls in your configs, set to "HTTPS" | +| alloy.livenessProbe | object | `{}` | Set livenessProbe for the Grafana Alloy container. | +| alloy.mounts.dockercontainers | bool | `false` | Mount /var/lib/docker/containers from the host into the container for log collection. | +| alloy.mounts.extra | list | `[]` | Extra volume mounts to add into the Grafana Alloy container. Does not affect the watch container. | +| alloy.mounts.varlog | bool | `false` | Mount /var/log from the host into the container for log collection. | +| alloy.resources | object | `{}` | Resource requests and limits to apply to the Grafana Alloy container. | +| alloy.securityContext | object | `{}` | Security context to apply to the Grafana Alloy container. | +| alloy.stabilityLevel | string | `"generally-available"` | Minimum stability level of components and behavior to enable. Must be one of "experimental", "public-preview", or "generally-available". | +| alloy.storagePath | string | `"/tmp/alloy"` | Path to where Grafana Alloy stores data (for example, the Write-Ahead Log). By default, data is lost between reboots. | +| alloy.uiPathPrefix | string | `"/"` | Base path where the UI is exposed. | +| configReloader.customArgs | list | `[]` | Override the args passed to the container. | +| configReloader.enabled | bool | `true` | Enables automatically reloading when the Alloy config changes. | +| configReloader.image.digest | string | `""` | SHA256 digest of image to use for config reloading (either in format "sha256:XYZ" or "XYZ"). When set, will override `configReloader.image.tag` | +| configReloader.image.registry | string | `"quay.io"` | Config reloader image registry (defaults to docker.io) | +| configReloader.image.repository | string | `"prometheus-operator/prometheus-config-reloader"` | Repository to get config reloader image from. | +| configReloader.image.tag | string | `"v0.81.0"` | Tag of image to use for config reloading. | +| configReloader.resources | object | `{"requests":{"cpu":"10m","memory":"50Mi"}}` | Resource requests and limits to apply to the config reloader container. | +| configReloader.securityContext | object | `{}` | Security context to apply to the Grafana configReloader container. | +| controller.affinity | object | `{}` | Affinity configuration for pods. | +| controller.autoscaling.enabled | bool | `false` | Creates a HorizontalPodAutoscaler for controller type deployment. Deprecated: Please use controller.autoscaling.horizontal instead | +| controller.autoscaling.horizontal | object | `{"enabled":false,"maxReplicas":5,"minReplicas":1,"scaleDown":{"policies":[],"selectPolicy":"Max","stabilizationWindowSeconds":300},"scaleUp":{"policies":[],"selectPolicy":"Max","stabilizationWindowSeconds":0},"targetCPUUtilizationPercentage":0,"targetMemoryUtilizationPercentage":80}` | Configures the Horizontal Pod Autoscaler for the controller. | +| controller.autoscaling.horizontal.enabled | bool | `false` | Enables the Horizontal Pod Autoscaler for the controller. | +| controller.autoscaling.horizontal.maxReplicas | int | `5` | The upper limit for the number of replicas to which the autoscaler can scale up. | +| controller.autoscaling.horizontal.minReplicas | int | `1` | The lower limit for the number of replicas to which the autoscaler can scale down. | +| controller.autoscaling.horizontal.scaleDown.policies | list | `[]` | List of policies to determine the scale-down behavior. | +| controller.autoscaling.horizontal.scaleDown.selectPolicy | string | `"Max"` | Determines which of the provided scaling-down policies to apply if multiple are specified. | +| controller.autoscaling.horizontal.scaleDown.stabilizationWindowSeconds | int | `300` | The duration that the autoscaling mechanism should look back on to make decisions about scaling down. | +| controller.autoscaling.horizontal.scaleUp.policies | list | `[]` | List of policies to determine the scale-up behavior. | +| controller.autoscaling.horizontal.scaleUp.selectPolicy | string | `"Max"` | Determines which of the provided scaling-up policies to apply if multiple are specified. | +| controller.autoscaling.horizontal.scaleUp.stabilizationWindowSeconds | int | `0` | The duration that the autoscaling mechanism should look back on to make decisions about scaling up. | +| controller.autoscaling.horizontal.targetCPUUtilizationPercentage | int | `0` | Average CPU utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetCPUUtilizationPercentage` to 0 will disable CPU scaling. | +| controller.autoscaling.horizontal.targetMemoryUtilizationPercentage | int | `80` | Average Memory utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetMemoryUtilizationPercentage` to 0 will disable Memory scaling. | +| controller.autoscaling.maxReplicas | int | `5` | The upper limit for the number of replicas to which the autoscaler can scale up. | +| controller.autoscaling.minReplicas | int | `1` | The lower limit for the number of replicas to which the autoscaler can scale down. | +| controller.autoscaling.scaleDown.policies | list | `[]` | List of policies to determine the scale-down behavior. | +| controller.autoscaling.scaleDown.selectPolicy | string | `"Max"` | Determines which of the provided scaling-down policies to apply if multiple are specified. | +| controller.autoscaling.scaleDown.stabilizationWindowSeconds | int | `300` | The duration that the autoscaling mechanism should look back on to make decisions about scaling down. | +| controller.autoscaling.scaleUp.policies | list | `[]` | List of policies to determine the scale-up behavior. | +| controller.autoscaling.scaleUp.selectPolicy | string | `"Max"` | Determines which of the provided scaling-up policies to apply if multiple are specified. | +| controller.autoscaling.scaleUp.stabilizationWindowSeconds | int | `0` | The duration that the autoscaling mechanism should look back on to make decisions about scaling up. | +| controller.autoscaling.targetCPUUtilizationPercentage | int | `0` | Average CPU utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetCPUUtilizationPercentage` to 0 will disable CPU scaling. | +| controller.autoscaling.targetMemoryUtilizationPercentage | int | `80` | Average Memory utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetMemoryUtilizationPercentage` to 0 will disable Memory scaling. | +| controller.autoscaling.vertical | object | `{"enabled":false,"recommenders":[],"resourcePolicy":{"containerPolicies":[{"containerName":"alloy","controlledResources":["cpu","memory"],"controlledValues":"RequestsAndLimits","maxAllowed":{},"minAllowed":{}}]},"updatePolicy":null}` | Configures the Vertical Pod Autoscaler for the controller. | +| controller.autoscaling.vertical.enabled | bool | `false` | Enables the Vertical Pod Autoscaler for the controller. | +| controller.autoscaling.vertical.recommenders | list | `[]` | List of recommenders to use for the Vertical Pod Autoscaler. Recommenders are responsible for generating recommendation for the object. List should be empty (then the default recommender will generate the recommendation) or contain exactly one recommender. | +| controller.autoscaling.vertical.resourcePolicy | object | `{"containerPolicies":[{"containerName":"alloy","controlledResources":["cpu","memory"],"controlledValues":"RequestsAndLimits","maxAllowed":{},"minAllowed":{}}]}` | Configures the resource policy for the Vertical Pod Autoscaler. | +| controller.autoscaling.vertical.resourcePolicy.containerPolicies | list | `[{"containerName":"alloy","controlledResources":["cpu","memory"],"controlledValues":"RequestsAndLimits","maxAllowed":{},"minAllowed":{}}]` | Configures the container policies for the Vertical Pod Autoscaler. | +| controller.autoscaling.vertical.resourcePolicy.containerPolicies[0].controlledResources | list | `["cpu","memory"]` | The controlled resources for the Vertical Pod Autoscaler. | +| controller.autoscaling.vertical.resourcePolicy.containerPolicies[0].controlledValues | string | `"RequestsAndLimits"` | The controlled values for the Vertical Pod Autoscaler. Needs to be either RequestsOnly or RequestsAndLimits. | +| controller.autoscaling.vertical.resourcePolicy.containerPolicies[0].maxAllowed | object | `{}` | The maximum allowed values for the pods. | +| controller.autoscaling.vertical.resourcePolicy.containerPolicies[0].minAllowed | object | `{}` | Defines the min allowed resources for the pod | +| controller.autoscaling.vertical.updatePolicy | string | `nil` | Configures the update policy for the Vertical Pod Autoscaler. | +| controller.dnsPolicy | string | `"ClusterFirst"` | Configures the DNS policy for the pod. https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy | +| controller.enableStatefulSetAutoDeletePVC | bool | `false` | Whether to enable automatic deletion of stale PVCs due to a scale down operation, when controller.type is 'statefulset'. | +| controller.extraAnnotations | object | `{}` | Annotations to add to controller. | +| controller.extraContainers | list | `[]` | Additional containers to run alongside the Alloy container and initContainers. | +| controller.hostNetwork | bool | `false` | Configures Pods to use the host network. When set to true, the ports that will be used must be specified. | +| controller.hostPID | bool | `false` | Configures Pods to use the host PID namespace. | +| controller.initContainers | list | `[]` | | +| controller.nodeSelector | object | `{}` | nodeSelector to apply to Grafana Alloy pods. | +| controller.parallelRollout | bool | `true` | Whether to deploy pods in parallel. Only used when controller.type is 'statefulset'. | +| controller.podAnnotations | object | `{}` | Extra pod annotations to add. | +| controller.podDisruptionBudget | object | `{"enabled":false,"maxUnavailable":null,"minAvailable":null}` | PodDisruptionBudget configuration. | +| controller.podDisruptionBudget.enabled | bool | `false` | Whether to create a PodDisruptionBudget for the controller. | +| controller.podDisruptionBudget.maxUnavailable | string | `nil` | Maximum number of pods that can be unavailable during a disruption. Note: Only one of minAvailable or maxUnavailable should be set. | +| controller.podDisruptionBudget.minAvailable | string | `nil` | Minimum number of pods that must be available during a disruption. Note: Only one of minAvailable or maxUnavailable should be set. | +| controller.podLabels | object | `{}` | Extra pod labels to add. | +| controller.priorityClassName | string | `""` | priorityClassName to apply to Grafana Alloy pods. | +| controller.replicas | int | `1` | Number of pods to deploy. Ignored when controller.type is 'daemonset'. | +| controller.terminationGracePeriodSeconds | string | `nil` | Termination grace period in seconds for the Grafana Alloy pods. The default value used by Kubernetes if unspecifed is 30 seconds. | +| controller.tolerations | list | `[]` | Tolerations to apply to Grafana Alloy pods. | +| controller.topologySpreadConstraints | list | `[]` | Topology Spread Constraints to apply to Grafana Alloy pods. | +| controller.type | string | `"daemonset"` | Type of controller to use for deploying Grafana Alloy in the cluster. Must be one of 'daemonset', 'deployment', or 'statefulset'. | +| controller.updateStrategy | object | `{}` | Update strategy for updating deployed Pods. | +| controller.volumeClaimTemplates | list | `[]` | volumeClaimTemplates to add when controller.type is 'statefulset'. | +| controller.volumes.extra | list | `[]` | Extra volumes to add to the Grafana Alloy pod. | +| crds.create | bool | `true` | Whether to install CRDs for monitoring. | +| extraObjects | list | `[]` | Extra k8s manifests to deploy | +| fullnameOverride | string | `nil` | Overrides the chart's computed fullname. Used to change the full prefix of resource names. | +| global.image.pullSecrets | list | `[]` | Optional set of global image pull secrets. | +| global.image.registry | string | `""` | Global image registry to use if it needs to be overridden for some specific use cases (e.g local registries, custom images, ...) | +| global.podSecurityContext | object | `{}` | Security context to apply to the Grafana Alloy pod. | +| image.digest | string | `nil` | Grafana Alloy image's SHA256 digest (either in format "sha256:XYZ" or "XYZ"). When set, will override `image.tag`. | +| image.pullPolicy | string | `"IfNotPresent"` | Grafana Alloy image pull policy. | +| image.pullSecrets | list | `[]` | Optional set of image pull secrets. | +| image.registry | string | `"docker.io"` | Grafana Alloy image registry (defaults to docker.io) | +| image.repository | string | `"grafana/alloy"` | Grafana Alloy image repository. | +| image.tag | string | `nil` | Grafana Alloy image tag. When empty, the Chart's appVersion is used. | +| ingress.annotations | object | `{}` | | +| ingress.enabled | bool | `false` | Enables ingress for Alloy (Faro port) | +| ingress.extraPaths | list | `[]` | | +| ingress.faroPort | int | `12347` | | +| ingress.hosts[0] | string | `"chart-example.local"` | | +| ingress.labels | object | `{}` | | +| ingress.path | string | `"/"` | | +| ingress.pathType | string | `"Prefix"` | | +| ingress.tls | list | `[]` | | +| nameOverride | string | `nil` | Overrides the chart's name. Used to change the infix in the resource names. | +| namespaceOverride | string | `nil` | Overrides the chart's namespace. | +| rbac.create | bool | `true` | Whether to create RBAC resources for Alloy. | +| service.annotations | object | `{}` | | +| service.clusterIP | string | `""` | Cluster IP, can be set to None, empty "" or an IP address | +| service.enabled | bool | `true` | Creates a Service for the controller's pods. | +| service.internalTrafficPolicy | string | `"Cluster"` | Value for internal traffic policy. 'Cluster' or 'Local' | +| service.nodePort | int | `31128` | NodePort port. Only takes effect when `service.type: NodePort` | +| service.type | string | `"ClusterIP"` | Service type | +| serviceAccount.additionalLabels | object | `{}` | Additional labels to add to the created service account. | +| serviceAccount.annotations | object | `{}` | Annotations to add to the created service account. | +| serviceAccount.automountServiceAccountToken | bool | `true` | | +| serviceAccount.create | bool | `true` | Whether to create a service account for the Grafana Alloy deployment. | +| serviceAccount.name | string | `nil` | The name of the existing service account to use when serviceAccount.create is false. | +| serviceMonitor.additionalLabels | object | `{}` | Additional labels for the service monitor. | +| serviceMonitor.enabled | bool | `false` | | +| serviceMonitor.interval | string | `""` | Scrape interval. If not set, the Prometheus default scrape interval is used. | +| serviceMonitor.metricRelabelings | list | `[]` | MetricRelabelConfigs to apply to samples after scraping, but before ingestion. ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig | +| serviceMonitor.relabelings | list | `[]` | RelabelConfigs to apply to samples before scraping ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig | +| serviceMonitor.tlsConfig | object | `{}` | Customize tls parameters for the service monitor | + +#### Migrate from `grafana/grafana-agent` chart to `grafana/alloy` + +The `values.yaml` file for the `grafana/grafana-agent` chart is compatible with +the chart for `grafana/alloy`, with two exceptions: + +* The `agent` field in `values.yaml` is deprecated in favor of `alloy`. Support + for the `agent` field will be removed in a future release. + +* The default value for `alloy.listenPort` is `12345` to align with the default + listen port in other installations. To retain the previous default, set + `alloy.listenPort` to `80` when installing. + +### alloy.stabilityLevel + +`alloy.stabilityLevel` controls the minimum level of stability for what +components can be created (directly or through imported modules). Note that +setting this field to a lower stability may also enable internal behaviour of a +lower stability, such as experimental memory optimizations. + +Valid settings are `experimental`, `public-preview`, and `generally-available`. + +### alloy.extraArgs + +`alloy.extraArgs` allows for passing extra arguments to the Grafana Alloy +container. The list of available arguments is documented on [alloy run][]. + +> **WARNING**: Using `alloy.extraArgs` does not have a stable API. Things may +> break between Chart upgrade if an argument gets added to the template. + +[alloy run]: https://grafana.com/docs/alloy/latest/reference/cli/run/ + +### alloy.extraPorts + +`alloy.extraPorts` allows for configuring specific open ports. + +The detained specification of ports can be found at the [Kubernetes Pod documents](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#ports). + +Port numbers specified must be 0 < x < 65535. + +| ChartPort | KubePort | Description | +|-----------|----------|-------------| +| targetPort | containerPort | Number of port to expose on the pod's IP address. | +| hostPort | hostPort | (Optional) Number of port to expose on the host. Daemonsets taking traffic might find this useful. | +| name | name | If specified, this must be an `IANA_SVC_NAME` and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. +| protocol | protocol | Must be UDP, TCP, or SCTP. Defaults to "TCP". | +| appProtocol | appProtocol | Hint on application protocol. This is used to expose Alloy externally on OpenShift clusters using "h2c". Optional. No default value. | + +### alloy.listenAddr + +`alloy.listenAddr` allows for restricting which address Alloy listens on +for network traffic on its HTTP server. By default, this is `0.0.0.0` to allow +its UI to be exposed when port-forwarding and to expose its metrics to other +Alloy instances in the cluster. + +### alloy.configMap.config + +`alloy.configMap.content` holds the Grafana Alloy configuration to use. + +If `alloy.configMap.content` is not provided, a [default configuration file][default-config] is +used. When provided, `alloy.configMap.content` must hold a valid Alloy configuration file. + +[default-config]: ./config/example.alloy + +### alloy.securityContext + +`alloy.securityContext` sets the securityContext passed to the Grafana +Alloy container. + +By default, Grafana Alloy containers are not able to collect telemetry from the +host node or other specific types of privileged telemetry data. See [Collecting +logs from other containers][#collecting-logs-from-other-containers] and +[Collecting host node telemetry][#collecting-host-node-telemetry] below for +more information on how to enable these capabilities. + +### rbac.create + +`rbac.create` enables the creation of ClusterRole and ClusterRoleBindings for +the Grafana Alloy containers to use. The default permission set allows +components like [discovery.kubernetes][] to work properly. + +[discovery.kubernetes]: https://grafana.com/docs/alloy/latest/reference/components/discovery.kubernetes/ + +### controller.autoscaling + +`controller.autoscaling.enabled` enables the creation of a HorizontalPodAutoscaler. It is only used when `controller.type` is set to `deployment` or `statefulset`. + +`controller.autoscaling` is intended to be used with [clustered][] mode. + +> **WARNING**: Using `controller.autoscaling` for any other Grafana Alloy +> configuration could lead to redundant or double telemetry collection. + +[clustered]: https://grafana.com/docs/alloy/latest/reference/cli/run/#clustered-mode + +When using autoscaling with a StatefulSet controller and have enabled +volumeClaimTemplates to be created alongside the StatefulSet, it is possible to +leak up to `maxReplicas` PVCs when the HPA is scaling down. If you're on +Kubernetes version `>=1.23-0` and your cluster has the +`StatefulSetAutoDeletePVC` feature gate enabled, you can set +`enableStatefulSetAutoDeletePVC` to true to automatically delete stale PVCs. + +Using `controller.autoscaling` requires the target metric (cpu/memory) to have +its resource requests set up for both the Alloy and config-reloader containers +so that the HPA can use them to calculate the replica count from the actual +resource utilization. + +## Collecting logs from other containers + +There are two ways to collect logs from other containers within the cluster +Alloy is deployed in. + +### loki.source.kubernetes + +The [loki.source.kubernetes][] component may be used to collect logs from +containers using the Kubernetes API. This component does not require mounting +the hosts filesystem into Alloy, nor requires additional security contexts to +work correctly. + +[loki.source.kubernetes]: https://grafana.com/docs/alloy/latest/reference/components/loki.source.kubernetes/ + +### File-based collection + +Logs may also be collected by mounting the host's filesystem into the Alloy +container, bypassing the need to communicate with the Kubrnetes API. + +To mount logs from other containers to Grafana Alloy directly: + +* Set `alloy.mounts.dockercontainers` to `true`. +* Set `alloy.securityContext` to: + ```yaml + privileged: true + runAsUser: 0 + ``` + +## Collecting host node telemetry + +Telemetry from the host, such as host-specific log files (from `/var/logs`) or +metrics from `/proc` and `/sys` are not accessible to Grafana Alloy containers. + +To expose this information to Grafana Alloy for telemetry collection: + +* Set `alloy.mounts.dockercontainers` to `true`. +* Mount `/proc` and `/sys` from the host into the container. +* Set `alloy.securityContext` to: + ```yaml + privileged: true + runAsUser: 0 + ``` + +## Expose Alloy externally on OpenShift clusters + +If you want to send telemetry from an Alloy instance outside of the OpenShift clusters over gRPC towards the Alloy instance on the OpenShift clusters, you need to: + +* Set the optional `appProtocol` on `alloy.extraPorts` to `h2c` +* Expose the service via Ingress or Route within the OpenShift cluster. Example of a Route in OpenShift: +```yaml +kind: Route +apiVersion: route.openshift.io/v1 +metadata: + name: route-otlp-alloy-h2c +spec: + to: + kind: Service + name: test-grpc-h2c + weight: 100 + port: + targetPort: otlp-grpc + tls: + termination: edge + insecureEdgeTerminationPolicy: Redirect + wildcardPolicy: None +``` + +Once this Ingress/Route is exposed it would then allow gRPC communication for (for example) traces. This allow an Alloy instance on a VM or another Kubernetes/OpenShift cluster to be able to communicate over gRPC via the exposed Ingress or Route. \ No newline at end of file diff --git a/charts/alloy/charts/crds/Chart.yaml b/charts/alloy/charts/crds/Chart.yaml new file mode 100644 index 0000000..adb9e4a --- /dev/null +++ b/charts/alloy/charts/crds/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: crds +version: 0.0.0 diff --git a/charts/alloy/charts/crds/crds/monitoring.grafana.com_podlogs.yaml b/charts/alloy/charts/crds/crds/monitoring.grafana.com_podlogs.yaml new file mode 100644 index 0000000..7867832 --- /dev/null +++ b/charts/alloy/charts/crds/crds/monitoring.grafana.com_podlogs.yaml @@ -0,0 +1,205 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: podlogs.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - grafana-alloy + - alloy + kind: PodLogs + listKind: PodLogsList + plural: podlogs + singular: podlogs + scope: Namespaced + versions: + - name: v1alpha2 + schema: + openAPIV3Schema: + description: PodLogs defines how to collect logs for a Pod. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: PodLogsSpec defines how to collect logs for a Pod. + properties: + namespaceSelector: + description: Selector to select which namespaces the Pod objects are + discovered from. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + relabelings: + description: RelabelConfigs to apply to logs before delivering. + items: + description: 'RelabelConfig allows dynamic rewriting of the label + set, being applied to samples before ingestion. It defines ``-section + of Prometheus configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on regex matching. Default + is 'replace'. uppercase and lowercase actions require Prometheus + >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + type: string + modulus: + description: Modulus to take of the hash of the source label + values. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. Default is '(.*)' + type: string + replacement: + description: Replacement value against which a regex replace + is performed if the regular expression matches. Regex capture + groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated source label + values. default is ';'. + type: string + sourceLabels: + description: The source labels select values from existing labels. + Their content is concatenated using the configured separator + and matched against the configured regular expression for + the replace, keep, and drop actions. + items: + description: LabelName is a valid Prometheus label name which + may only contain ASCII letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting value is written in + a replace action. It is mandatory for replace actions. Regex + capture groups are available. + type: string + type: object + type: array + selector: + description: Selector to select Pod objects. Required. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - selector + type: object + type: object + served: true + storage: true diff --git a/charts/alloy/ci/additional-serviceaccount-label-values.yaml b/charts/alloy/ci/additional-serviceaccount-label-values.yaml new file mode 100644 index 0000000..91b7cbb --- /dev/null +++ b/charts/alloy/ci/additional-serviceaccount-label-values.yaml @@ -0,0 +1,3 @@ +serviceAccount: + additionalLabels: + test: "true" diff --git a/charts/alloy/ci/clustering-values.yaml b/charts/alloy/ci/clustering-values.yaml new file mode 100644 index 0000000..4a0c468 --- /dev/null +++ b/charts/alloy/ci/clustering-values.yaml @@ -0,0 +1,7 @@ +alloy: + clustering: + enabled: true + +controller: + type: 'statefulset' + replicas: 3 diff --git a/charts/alloy/ci/controller-deployment-pdb-max-unavailable-values.yaml b/charts/alloy/ci/controller-deployment-pdb-max-unavailable-values.yaml new file mode 100644 index 0000000..1bddddc --- /dev/null +++ b/charts/alloy/ci/controller-deployment-pdb-max-unavailable-values.yaml @@ -0,0 +1,5 @@ +controller: + type: deployment + podDisruptionBudget: + enabled: true + maxUnavailable: 1 diff --git a/charts/alloy/ci/controller-deployment-pdb-min-available-values.yaml b/charts/alloy/ci/controller-deployment-pdb-min-available-values.yaml new file mode 100644 index 0000000..f9879cc --- /dev/null +++ b/charts/alloy/ci/controller-deployment-pdb-min-available-values.yaml @@ -0,0 +1,5 @@ +controller: + type: deployment + podDisruptionBudget: + enabled: true + minAvailable: 1 diff --git a/charts/alloy/ci/controller-statefulset-pdb-max-unavailable-values.yaml b/charts/alloy/ci/controller-statefulset-pdb-max-unavailable-values.yaml new file mode 100644 index 0000000..0aaf358 --- /dev/null +++ b/charts/alloy/ci/controller-statefulset-pdb-max-unavailable-values.yaml @@ -0,0 +1,5 @@ +controller: + type: statefulset + podDisruptionBudget: + enabled: true + maxUnavailable: 1 diff --git a/charts/alloy/ci/controller-statefulset-pdb-min-available-values.yaml b/charts/alloy/ci/controller-statefulset-pdb-min-available-values.yaml new file mode 100644 index 0000000..b8dbcbf --- /dev/null +++ b/charts/alloy/ci/controller-statefulset-pdb-min-available-values.yaml @@ -0,0 +1,5 @@ +controller: + type: statefulset + podDisruptionBudget: + enabled: true + minAvailable: 1 diff --git a/charts/alloy/ci/controller-volumes-extra-values.yaml b/charts/alloy/ci/controller-volumes-extra-values.yaml new file mode 100644 index 0000000..2486c59 --- /dev/null +++ b/charts/alloy/ci/controller-volumes-extra-values.yaml @@ -0,0 +1,12 @@ +controller: + volumes: + extra: + - name: cache-volume + emptyDir: + sizeLimit: 500Mi + +alloy: + mounts: + extra: + - mountPath: /cache + name: cache-volume diff --git a/charts/alloy/ci/create-daemonset-hostnetwork-values.yaml b/charts/alloy/ci/create-daemonset-hostnetwork-values.yaml new file mode 100644 index 0000000..61d05b1 --- /dev/null +++ b/charts/alloy/ci/create-daemonset-hostnetwork-values.yaml @@ -0,0 +1,5 @@ +# Test rendering of the chart with the controller explicitly set to DaemonSet. +controller: + type: daemonset + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet diff --git a/charts/alloy/ci/create-daemonset-values.yaml b/charts/alloy/ci/create-daemonset-values.yaml new file mode 100644 index 0000000..13b7a39 --- /dev/null +++ b/charts/alloy/ci/create-daemonset-values.yaml @@ -0,0 +1,3 @@ +# Test rendering of the chart with the controller explicitly set to DaemonSet. +controller: + type: daemonset diff --git a/charts/alloy/ci/create-deployment-autoscaling-values.yaml b/charts/alloy/ci/create-deployment-autoscaling-values.yaml new file mode 100644 index 0000000..2db66b8 --- /dev/null +++ b/charts/alloy/ci/create-deployment-autoscaling-values.yaml @@ -0,0 +1,26 @@ +# Test rendering of the chart with the controller explicitly set to Deployment and autoscaling enabled. +controller: + type: deployment + autoscaling: + horizontal: + enabled: true + scaleDown: + policies: + - type: Pods + value: 4 + periodSeconds: 60 + selectPolicy: Min + stabilizationWindowSeconds: 100 + scaleUp: + policies: + - type: Pods + value: 4 + periodSeconds: 60 + - type: Percent + value: 100 + periodSeconds: 15 + stabilizationWindowSeconds: 80 +alloy: + resources: + requests: + memory: 100Mi diff --git a/charts/alloy/ci/create-deployment-values.yaml b/charts/alloy/ci/create-deployment-values.yaml new file mode 100644 index 0000000..4763b4b --- /dev/null +++ b/charts/alloy/ci/create-deployment-values.yaml @@ -0,0 +1,3 @@ +# Test rendering of the chart with the controller explicitly set to Deployment. +controller: + type: deployment diff --git a/charts/alloy/ci/create-statefulset-autoscaling-values.yaml b/charts/alloy/ci/create-statefulset-autoscaling-values.yaml new file mode 100644 index 0000000..7ab438e --- /dev/null +++ b/charts/alloy/ci/create-statefulset-autoscaling-values.yaml @@ -0,0 +1,26 @@ +# Test rendering of the chart with the controller explicitly set to StatefulSet and autoscaling the old way enabled. +controller: + type: statefulset + autoscaling: + enabled: true + scaleDown: + policies: + - type: Pods + value: 4 + periodSeconds: 60 + selectPolicy: Min + stabilizationWindowSeconds: 100 + scaleUp: + policies: + - type: Pods + value: 4 + periodSeconds: 60 + - type: Percent + value: 100 + periodSeconds: 15 + stabilizationWindowSeconds: 80 + enableStatefulSetAutoDeletePVC: true +alloy: + resources: + requests: + memory: 100Mi diff --git a/charts/alloy/ci/create-statefulset-values.yaml b/charts/alloy/ci/create-statefulset-values.yaml new file mode 100644 index 0000000..51c7c19 --- /dev/null +++ b/charts/alloy/ci/create-statefulset-values.yaml @@ -0,0 +1,3 @@ +# Test rendering of the chart with the controller explicitly set to StatefulSet. +controller: + type: statefulset diff --git a/charts/alloy/ci/custom-config-values.yaml b/charts/alloy/ci/custom-config-values.yaml new file mode 100644 index 0000000..ebfce09 --- /dev/null +++ b/charts/alloy/ci/custom-config-values.yaml @@ -0,0 +1,10 @@ +alloy: + configMap: + content: |- + logging { + level = "warn" + format = "logfmt" + } + discovery.kubernetes "custom_pods" { + role = "pod" + } diff --git a/charts/alloy/ci/default-values-values.yaml b/charts/alloy/ci/default-values-values.yaml new file mode 100644 index 0000000..3724bea --- /dev/null +++ b/charts/alloy/ci/default-values-values.yaml @@ -0,0 +1 @@ +# Test rendering of the chart with everything set to the default values. diff --git a/charts/alloy/ci/enable-servicemonitor-tls-values.yaml b/charts/alloy/ci/enable-servicemonitor-tls-values.yaml new file mode 100644 index 0000000..26662f3 --- /dev/null +++ b/charts/alloy/ci/enable-servicemonitor-tls-values.yaml @@ -0,0 +1,9 @@ +# Test rendering of the chart with the service monitor enabled +alloy: + listenScheme: HTTPS +service: + enabled: true +serviceMonitor: + enabled: true + tlsConfig: + insecureSkipVerify: true diff --git a/charts/alloy/ci/enable-servicemonitor-values.yaml b/charts/alloy/ci/enable-servicemonitor-values.yaml new file mode 100644 index 0000000..837bf3f --- /dev/null +++ b/charts/alloy/ci/enable-servicemonitor-values.yaml @@ -0,0 +1,5 @@ +# Test rendering of the chart with the service monitor enabled +service: + enabled: true +serviceMonitor: + enabled: true diff --git a/charts/alloy/ci/envFrom-values.yaml b/charts/alloy/ci/envFrom-values.yaml new file mode 100644 index 0000000..8d90148 --- /dev/null +++ b/charts/alloy/ci/envFrom-values.yaml @@ -0,0 +1,5 @@ +# Specify extra ports for verifying rendering the template works +alloy: + envFrom: + - configMapRef: + name: special-config diff --git a/charts/alloy/ci/existing-config-values.yaml b/charts/alloy/ci/existing-config-values.yaml new file mode 100644 index 0000000..5eeeb42 --- /dev/null +++ b/charts/alloy/ci/existing-config-values.yaml @@ -0,0 +1,5 @@ +alloy: + configMap: + create: false + name: existing-config + key: my-config.alloy diff --git a/charts/alloy/ci/extra-env-values.yaml b/charts/alloy/ci/extra-env-values.yaml new file mode 100644 index 0000000..7d444f1 --- /dev/null +++ b/charts/alloy/ci/extra-env-values.yaml @@ -0,0 +1,9 @@ +# Specify extra ports for verifying rendering the template works +alloy: + extraEnv: + - name: GREETING + value: "Warm greetings to" + - name: HONORIFIC + value: "The Most Honorable" + - name: NAME + value: "Kubernetes" diff --git a/charts/alloy/ci/extra-manifests-values.yaml b/charts/alloy/ci/extra-manifests-values.yaml new file mode 100644 index 0000000..324c44a --- /dev/null +++ b/charts/alloy/ci/extra-manifests-values.yaml @@ -0,0 +1,8 @@ +extraObjects: +- apiVersion: v1 + kind: Secret + metadata: + name: grafana-cloud + stringData: + PROMETHEUS_HOST: 'https://prometheus-us-central1.grafana.net/api/prom/push' + PROMETHEUS_USERNAME: '123456' diff --git a/charts/alloy/ci/extra-ports-values.yaml b/charts/alloy/ci/extra-ports-values.yaml new file mode 100644 index 0000000..d29a0e5 --- /dev/null +++ b/charts/alloy/ci/extra-ports-values.yaml @@ -0,0 +1,7 @@ +# Specify extra ports for verifying rendering the template works +alloy: + extraPorts: + - name: jaeger-thrift + port: 14268 + targetPort: 14268 + protocol: TCP diff --git a/charts/alloy/ci/faro-ingress-values.yaml b/charts/alloy/ci/faro-ingress-values.yaml new file mode 100644 index 0000000..3f09d88 --- /dev/null +++ b/charts/alloy/ci/faro-ingress-values.yaml @@ -0,0 +1,9 @@ +alloy: + extraPorts: + - name: "faro" + port: 12347 + targetPort: 12347 + protocol: "TCP" + +ingress: + enabled: true diff --git a/charts/alloy/ci/global-image-pullsecrets-values.yaml b/charts/alloy/ci/global-image-pullsecrets-values.yaml new file mode 100644 index 0000000..30069cf --- /dev/null +++ b/charts/alloy/ci/global-image-pullsecrets-values.yaml @@ -0,0 +1,13 @@ +# Test rendering of the chart with the global image pull secret explicitly set. +global: + image: + pullSecrets: + - name: global-cred + + podSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + +image: + pullSecrets: + - name: local-cred diff --git a/charts/alloy/ci/global-image-registry-values.yaml b/charts/alloy/ci/global-image-registry-values.yaml new file mode 100644 index 0000000..f4c2d30 --- /dev/null +++ b/charts/alloy/ci/global-image-registry-values.yaml @@ -0,0 +1,11 @@ +# Test rendering of the chart with the global image registry explicitly set to another value. +global: + image: + registry: quay.io + +image: + registry: docker.com # Invalid value by default + +configReloader: + image: + registry: docker.com diff --git a/charts/alloy/ci/host-alias-values.yaml b/charts/alloy/ci/host-alias-values.yaml new file mode 100644 index 0000000..1b7f5a9 --- /dev/null +++ b/charts/alloy/ci/host-alias-values.yaml @@ -0,0 +1,5 @@ +alloy: + hostAliases: + - ip: "20.21.22.23" + hostnames: + - "grafana.company.net" diff --git a/charts/alloy/ci/initcontainers-values.yaml b/charts/alloy/ci/initcontainers-values.yaml new file mode 100644 index 0000000..4c74c93 --- /dev/null +++ b/charts/alloy/ci/initcontainers-values.yaml @@ -0,0 +1,29 @@ +controller: + initContainers: + - name: geo-ip + image: ghcr.io/maxmind/geoipupdate:v6.0 + volumeMounts: + - name: geoip + mountPath: /etc/geoip + volumes: + - name: geoip + emptyDir: {} + env: + - name: GEOIPUPDATE_ACCOUNT_ID + value: "geoipupdate_account_id" + - name: GEOIPUPDATE_LICENSE_KEY + value: "geoipupdate_license_key" + - name: GEOIPUPDATE_EDITION_IDS + value: "GeoLite2-ASN GeoLite2-City GeoLite2-Country" + - name: GEOIPUPDATE_DB_DIR + value: "/etc/geoip" + volumes: + extra: + - name: geoip + mountPath: /etc/geoip + +alloy: + mounts: + extra: + - name: geoip + mountPath: /etc/geoip diff --git a/charts/alloy/ci/lifecycle-hooks-values.yaml b/charts/alloy/ci/lifecycle-hooks-values.yaml new file mode 100644 index 0000000..97fcfef --- /dev/null +++ b/charts/alloy/ci/lifecycle-hooks-values.yaml @@ -0,0 +1,8 @@ +controller: + type: deployment + +alloy: + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "sleep 1"] diff --git a/charts/alloy/ci/livinessprobe-values.yaml b/charts/alloy/ci/livinessprobe-values.yaml new file mode 100644 index 0000000..8badd2b --- /dev/null +++ b/charts/alloy/ci/livinessprobe-values.yaml @@ -0,0 +1,11 @@ +alloy: + livenessProbe: + httpGet: + path: /metrics + port: 12345 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 2 + periodSeconds: 30 + successThreshold: 1 + failureThreshold: 3 diff --git a/charts/alloy/ci/local-image-pullsecrets-values.yaml b/charts/alloy/ci/local-image-pullsecrets-values.yaml new file mode 100644 index 0000000..a7a800f --- /dev/null +++ b/charts/alloy/ci/local-image-pullsecrets-values.yaml @@ -0,0 +1,4 @@ +# Test rendering of the chart with the image pull secret explicitly set. +image: + pullSecrets: + - name: local-cred diff --git a/charts/alloy/ci/local-image-registry-values.yaml b/charts/alloy/ci/local-image-registry-values.yaml new file mode 100644 index 0000000..79fbc67 --- /dev/null +++ b/charts/alloy/ci/local-image-registry-values.yaml @@ -0,0 +1,7 @@ +# Test rendering of the chart with the individual image registries explicitly set to another value. +image: + registry: quay.io + +configReloader: + image: + registry: quay.io diff --git a/charts/alloy/ci/nodeselectors-and-tolerations-values.yaml b/charts/alloy/ci/nodeselectors-and-tolerations-values.yaml new file mode 100644 index 0000000..812c271 --- /dev/null +++ b/charts/alloy/ci/nodeselectors-and-tolerations-values.yaml @@ -0,0 +1,11 @@ +controller: + nodeSelector: + key1: "value1" + tolerations: + - key: "key1" + operator: "Equal" + value: "value1" + effect: "NoSchedule" + - key: "key2" + operator: "Exists" + effect: "NoSchedule" diff --git a/charts/alloy/ci/nonroot-values.yaml b/charts/alloy/ci/nonroot-values.yaml new file mode 100644 index 0000000..34714be --- /dev/null +++ b/charts/alloy/ci/nonroot-values.yaml @@ -0,0 +1,7 @@ +global: + podSecurityContext: + fsGroup: 473 +alloy: + securityContext: + runAsUser: 473 + runAsGroup: 473 diff --git a/charts/alloy/ci/pod_annotations-values.yaml b/charts/alloy/ci/pod_annotations-values.yaml new file mode 100644 index 0000000..6af944e --- /dev/null +++ b/charts/alloy/ci/pod_annotations-values.yaml @@ -0,0 +1,4 @@ +# Test correct rendering of the pod annotations +controller: + podAnnotations: + testAnnotationKey: testAnnotationValue diff --git a/charts/alloy/ci/sidecars-values.yaml b/charts/alloy/ci/sidecars-values.yaml new file mode 100644 index 0000000..763c546 --- /dev/null +++ b/charts/alloy/ci/sidecars-values.yaml @@ -0,0 +1,29 @@ +controller: + extraContainers: + - name: geo-ip + image: ghcr.io/maxmind/geoipupdate:v6.0 + volumeMounts: + - name: geoip + mountPath: /etc/geoip + volumes: + - name: geoip + emptyDir: {} + env: + - name: GEOIPUPDATE_ACCOUNT_ID + value: "geoipupdate_account_id" + - name: GEOIPUPDATE_LICENSE_KEY + value: "geoipupdate_license_key" + - name: GEOIPUPDATE_EDITION_IDS + value: "GeoLite2-ASN GeoLite2-City GeoLite2-Country" + - name: GEOIPUPDATE_DB_DIR + value: "/etc/geoip" + volumes: + extra: + - name: geoip + mountPath: /etc/geoip + +alloy: + mounts: + extra: + - name: geoip + mountPath: /etc/geoip diff --git a/charts/alloy/ci/termination-grace-period-values.yaml b/charts/alloy/ci/termination-grace-period-values.yaml new file mode 100644 index 0000000..4ff8b98 --- /dev/null +++ b/charts/alloy/ci/termination-grace-period-values.yaml @@ -0,0 +1,3 @@ +controller: + type: deployment + terminationGracePeriodSeconds: 20 diff --git a/charts/alloy/ci/topologyspreadconstraints-values.yaml b/charts/alloy/ci/topologyspreadconstraints-values.yaml new file mode 100644 index 0000000..9b98df4 --- /dev/null +++ b/charts/alloy/ci/topologyspreadconstraints-values.yaml @@ -0,0 +1,10 @@ +controller: + type: deployment + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: alloy + app.kubernetes.io/instance: alloy diff --git a/charts/alloy/ci/with-digests-values.yaml b/charts/alloy/ci/with-digests-values.yaml new file mode 100644 index 0000000..d742dd2 --- /dev/null +++ b/charts/alloy/ci/with-digests-values.yaml @@ -0,0 +1,10 @@ +image: + registry: "docker.io" + repository: "grafana/agent" + digest: "sha256:82575a7be3e4770e53f620298e58bcc4cdb0fd0338e01c4b206cae9e3ca46ebf" + +configReloader: + image: + registry: "docker.io" + repository: "jimmidyson/configmap-reload" + digest: "sha256:5af9d3041d12a3e63f115125f89b66d2ba981fe82e64302ac370c5496055059c" diff --git a/charts/alloy/config/example.alloy b/charts/alloy/config/example.alloy new file mode 100644 index 0000000..e356547 --- /dev/null +++ b/charts/alloy/config/example.alloy @@ -0,0 +1,28 @@ +logging { + level = "info" + format = "logfmt" +} + +discovery.kubernetes "pods" { + role = "pod" +} + +discovery.kubernetes "nodes" { + role = "node" +} + +discovery.kubernetes "services" { + role = "service" +} + +discovery.kubernetes "endpoints" { + role = "endpoints" +} + +discovery.kubernetes "endpointslices" { + role = "endpointslice" +} + +discovery.kubernetes "ingresses" { + role = "ingress" +} diff --git a/charts/alloy/templates/NOTES.txt b/charts/alloy/templates/NOTES.txt new file mode 100644 index 0000000..2c3176b --- /dev/null +++ b/charts/alloy/templates/NOTES.txt @@ -0,0 +1 @@ +Welcome to Grafana Alloy! diff --git a/charts/alloy/templates/_config.tpl b/charts/alloy/templates/_config.tpl new file mode 100644 index 0000000..54b8225 --- /dev/null +++ b/charts/alloy/templates/_config.tpl @@ -0,0 +1,25 @@ +{{/* +Retrieve configMap name from the name of the chart or the ConfigMap the user +specified. +*/}} +{{- define "alloy.config-map.name" -}} +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if $values.configMap.name -}} +{{- $values.configMap.name }} +{{- else -}} +{{- include "alloy.fullname" . }} +{{- end }} +{{- end }} + +{{/* +The name of the config file is the default or the key the user specified in the +ConfigMap. +*/}} +{{- define "alloy.config-map.key" -}} +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if $values.configMap.key -}} +{{- $values.configMap.key }} +{{- else -}} +config.alloy +{{- end }} +{{- end }} diff --git a/charts/alloy/templates/_helpers.tpl b/charts/alloy/templates/_helpers.tpl new file mode 100644 index 0000000..2695f9c --- /dev/null +++ b/charts/alloy/templates/_helpers.tpl @@ -0,0 +1,162 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "alloy.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +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 "alloy.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "alloy.chart" -}} +{{- if index .Values "$chart_tests" }} +{{- printf "%s" .Chart.Name | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "alloy.namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "alloy.labels" -}} +helm.sh/chart: {{ include "alloy.chart" . }} +{{ include "alloy.selectorLabels" . }} +{{- if index .Values "$chart_tests" }} +app.kubernetes.io/version: "vX.Y.Z" +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- else -}} +{{/* substr trims delimeter prefix char from alloy.imageId output + e.g. ':' for tags and '@' for digests. + For digests, we crop the string to a 7-char (short) sha. */}} +app.kubernetes.io/version: {{ (include "alloy.imageId" .) | trunc 15 | trimPrefix "@sha256" | trimPrefix ":" | quote }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/part-of: alloy +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "alloy.selectorLabels" -}} +app.kubernetes.io/name: {{ include "alloy.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "alloy.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "alloy.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Calculate name of image ID to use for "alloy. +*/}} +{{- define "alloy.imageId" -}} +{{- if .Values.image.digest }} +{{- $digest := .Values.image.digest }} +{{- if not (hasPrefix "sha256:" $digest) }} +{{- $digest = printf "sha256:%s" $digest }} +{{- end }} +{{- printf "@%s" $digest }} +{{- else if .Values.image.tag }} +{{- printf ":%s" .Values.image.tag }} +{{- else }} +{{- printf ":%s" .Chart.AppVersion }} +{{- end }} +{{- end }} + +{{/* +Calculate name of image ID to use for "config-reloader". +*/}} +{{- define "config-reloader.imageId" -}} +{{- if .Values.configReloader.image.digest }} +{{- $digest := .Values.configReloader.image.digest }} +{{- if not (hasPrefix "sha256:" $digest) }} +{{- $digest = printf "sha256:%s" $digest }} +{{- end }} +{{- printf "@%s" $digest }} +{{- else if .Values.configReloader.image.tag }} +{{- printf ":%s" .Values.configReloader.image.tag }} +{{- else }} +{{- printf ":%s" "v0.8.0" }} +{{- end }} +{{- end }} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "alloy.ingress.apiVersion" -}} +{{- if and ($.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19-0" .Capabilities.KubeVersion.Version) }} +{{- print "networking.k8s.io/v1" }} +{{- else if $.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} +{{- print "networking.k8s.io/v1beta1" }} +{{- else }} +{{- print "extensions/v1beta1" }} +{{- end }} +{{- end }} + +{{/* +Return if ingress is stable. +*/}} +{{- define "alloy.ingress.isStable" -}} +{{- eq (include "alloy.ingress.apiVersion" .) "networking.k8s.io/v1" }} +{{- end }} + +{{/* +Return if ingress supports ingressClassName. +*/}} +{{- define "alloy.ingress.supportsIngressClassName" -}} +{{- or (eq (include "alloy.ingress.isStable" .) "true") (and (eq (include "alloy.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) }} +{{- end }} +{{/* +Return if ingress supports pathType. +*/}} +{{- define "alloy.ingress.supportsPathType" -}} +{{- or (eq (include "alloy.ingress.isStable" .) "true") (and (eq (include "alloy.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) }} +{{- end }} + +{{/* +Return the appropriate apiVersion for PodDisruptionBudget. +*/}} +{{- define "alloy.controller.pdb.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "policy/v1") (semverCompare ">=1.21-0" .Capabilities.KubeVersion.Version) -}} + {{- print "policy/v1" -}} + {{- else -}} + {{- print "policy/v1beta1" -}} + {{- end -}} +{{- end -}} diff --git a/charts/alloy/templates/cluster_service.yaml b/charts/alloy/templates/cluster_service.yaml new file mode 100644 index 0000000..090ad52 --- /dev/null +++ b/charts/alloy/templates/cluster_service.yaml @@ -0,0 +1,38 @@ +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if $values.clustering.enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "alloy.fullname" . }}-cluster + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: networking +spec: + type: ClusterIP + clusterIP: 'None' + publishNotReadyAddresses: true + selector: + {{- include "alloy.selectorLabels" . | nindent 4 }} + ports: + # Do not include the -metrics suffix in the port name, otherwise metrics + # can be double-collected with the non-headless Service if it's also + # enabled. + # + # This service should only be used for clustering, and not metric + # collection. + - name: {{ $values.clustering.portName }} + port: {{ $values.listenPort }} + targetPort: {{ $values.listenPort }} + protocol: "TCP" + {{- range $portMap := $values.extraPorts }} + - name: {{ $portMap.name }} + port: {{ $portMap.port }} + targetPort: {{ $portMap.targetPort }} + protocol: {{ coalesce $portMap.protocol "TCP" }} + {{- if not (empty $portMap.appProtocol) }} + # Useful for OpenShift clusters that want to expose Alloy ports externally + appProtocol: {{ $portMap.appProtocol }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/alloy/templates/configmap.yaml b/charts/alloy/templates/configmap.yaml new file mode 100644 index 0000000..1acadef --- /dev/null +++ b/charts/alloy/templates/configmap.yaml @@ -0,0 +1,17 @@ +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if $values.configMap.create }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "alloy.config-map.name" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: config +data: + {{- if $values.configMap.content }} + config.alloy: |- {{- (tpl $values.configMap.content .) | nindent 4 }} + {{- else }} + config.alloy: |- {{- .Files.Get "config/example.alloy" | trim | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/alloy/templates/containers/_agent.yaml b/charts/alloy/templates/containers/_agent.yaml new file mode 100644 index 0000000..89968b7 --- /dev/null +++ b/charts/alloy/templates/containers/_agent.yaml @@ -0,0 +1,92 @@ +{{- define "alloy.container" -}} +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +- name: alloy + image: {{ .Values.global.image.registry | default .Values.image.registry }}/{{ .Values.image.repository }}{{ include "alloy.imageId" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - run + - /etc/alloy/{{ include "alloy.config-map.key" . }} + - --storage.path={{ $values.storagePath }} + - --server.http.listen-addr={{ $values.listenAddr }}:{{ $values.listenPort }} + - --server.http.ui-path-prefix={{ $values.uiPathPrefix }} + {{- if not $values.enableReporting }} + - --disable-reporting + {{- end}} + {{- if $values.clustering.enabled }} + - --cluster.enabled=true + - --cluster.join-addresses={{ include "alloy.fullname" . }}-cluster + {{- if $values.clustering.name }} + - --cluster.name={{ $values.clustering.name }} + {{- end}} + {{- end}} + {{- if $values.stabilityLevel }} + - --stability.level={{ $values.stabilityLevel }} + {{- end }} + {{- range $values.extraArgs }} + - {{ . }} + {{- end}} + env: + - name: ALLOY_DEPLOY_MODE + value: "helm" + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{- range $values.extraEnv }} + - {{- toYaml . | nindent 6 }} + {{- end }} + {{- if $values.envFrom }} + envFrom: + {{- toYaml $values.envFrom | nindent 4 }} + {{- end }} + ports: + - containerPort: {{ $values.listenPort }} + name: http-metrics + {{- range $portMap := $values.extraPorts }} + - containerPort: {{ $portMap.targetPort }} + {{- if $portMap.hostPort }} + hostPort: {{ $portMap.hostPort }} + {{- end}} + name: {{ $portMap.name }} + protocol: {{ coalesce $portMap.protocol "TCP" }} + {{- end }} + readinessProbe: + httpGet: + path: /-/ready + port: {{ $values.listenPort }} + scheme: {{ $values.listenScheme }} + initialDelaySeconds: 10 + timeoutSeconds: 1 + {{- with $values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $values.resources }} + resources: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $values.lifecycle }} + lifecycle: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $values.securityContext }} + securityContext: + {{- toYaml . | nindent 4 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/alloy + {{- if $values.mounts.varlog }} + - name: varlog + mountPath: /var/log + readOnly: true + {{- end }} + {{- if $values.mounts.dockercontainers }} + - name: dockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + {{- end }} + {{- range $values.mounts.extra }} + - {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/alloy/templates/containers/_watch.yaml b/charts/alloy/templates/containers/_watch.yaml new file mode 100644 index 0000000..d17dc31 --- /dev/null +++ b/charts/alloy/templates/containers/_watch.yaml @@ -0,0 +1,26 @@ +{{- define "alloy.watch-container" -}} +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if .Values.configReloader.enabled -}} +- name: config-reloader + image: {{ .Values.global.image.registry | default .Values.configReloader.image.registry }}/{{ .Values.configReloader.image.repository }}{{ include "config-reloader.imageId" . }} + {{- if .Values.configReloader.customArgs }} + args: + {{- toYaml .Values.configReloader.customArgs | nindent 4 }} + {{- else }} + args: + - --watched-dir=/etc/alloy + - --reload-url=http://localhost:{{ $values.listenPort }}/-/reload + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/alloy + {{- with .Values.configReloader.resources }} + resources: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.configReloader.securityContext }} + securityContext: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- end -}} diff --git a/charts/alloy/templates/controllers/_pod.yaml b/charts/alloy/templates/controllers/_pod.yaml new file mode 100644 index 0000000..453bdfd --- /dev/null +++ b/charts/alloy/templates/controllers/_pod.yaml @@ -0,0 +1,93 @@ +{{- define "alloy.pod-template" -}} +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +metadata: + annotations: + kubectl.kubernetes.io/default-container: alloy + {{- if and $values.configMap.create $values.configMap.content }} + checksum/config: {{ (tpl $values.configMap.content .) | sha256sum | trunc 63 }} + {{- end }} + {{- with .Values.controller.podAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "alloy.selectorLabels" . | nindent 4 }} + {{- with .Values.controller.podLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.global.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 4 }} + {{- end }} + serviceAccountName: {{ include "alloy.serviceAccountName" . }} + {{- if or .Values.global.image.pullSecrets .Values.image.pullSecrets }} + imagePullSecrets: + {{- if .Values.global.image.pullSecrets }} + {{- toYaml .Values.global.image.pullSecrets | nindent 4 }} + {{- else }} + {{- toYaml .Values.image.pullSecrets | nindent 4 }} + {{- end }} + {{- end }} + {{- if .Values.controller.initContainers }} + initContainers: + {{- with .Values.controller.initContainers }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + containers: + {{- include "alloy.container" . | nindent 4 }} + {{- include "alloy.watch-container" . | nindent 4 }} + {{- with .Values.controller.extraContainers }} + {{- toYaml . | nindent 4 }} + {{- end}} + {{- if .Values.controller.priorityClassName }} + priorityClassName: {{ .Values.controller.priorityClassName }} + {{- end }} + {{- if .Values.controller.hostNetwork }} + hostNetwork: {{ .Values.controller.hostNetwork }} + {{- end }} + {{- if .Values.controller.hostPID }} + hostPID: {{ .Values.controller.hostPID }} + {{- end }} + dnsPolicy: {{ .Values.controller.dnsPolicy }} + {{- with .Values.controller.affinity }} + affinity: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.controller.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds | int }} + {{- end }} + {{- with .Values.controller.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.controller.tolerations }} + tolerations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.controller.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 4 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "alloy.config-map.name" . }} + {{- if $values.mounts.varlog }} + - name: varlog + hostPath: + path: /var/log + {{- end }} + {{- if $values.mounts.dockercontainers }} + - name: dockercontainers + hostPath: + path: /var/lib/docker/containers + {{- end }} + {{- if .Values.controller.volumes.extra }} + {{- toYaml .Values.controller.volumes.extra | nindent 4 }} + {{- end }} + {{- if $values.hostAliases }} + hostAliases: + {{- toYaml $values.hostAliases | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/alloy/templates/controllers/daemonset.yaml b/charts/alloy/templates/controllers/daemonset.yaml new file mode 100644 index 0000000..b692995 --- /dev/null +++ b/charts/alloy/templates/controllers/daemonset.yaml @@ -0,0 +1,26 @@ +{{- if eq .Values.controller.type "daemonset" }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + {{- with .Values.controller.extraAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if ge (int .Capabilities.KubeVersion.Minor) 22 }} + minReadySeconds: 10 + {{- end }} + selector: + matchLabels: + {{- include "alloy.selectorLabels" . | nindent 6 }} + template: + {{- include "alloy.pod-template" . | nindent 4 }} + {{- with .Values.controller.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/alloy/templates/controllers/deployment.yaml b/charts/alloy/templates/controllers/deployment.yaml new file mode 100644 index 0000000..07d6912 --- /dev/null +++ b/charts/alloy/templates/controllers/deployment.yaml @@ -0,0 +1,29 @@ +{{- if eq .Values.controller.type "deployment" }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + {{- with .Values.controller.extraAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if not .Values.controller.autoscaling.enabled }} + replicas: {{ .Values.controller.replicas }} + {{- end }} + {{- if ge (int .Capabilities.KubeVersion.Minor) 22 }} + minReadySeconds: 10 + {{- end }} + selector: + matchLabels: + {{- include "alloy.selectorLabels" . | nindent 6 }} + template: + {{- include "alloy.pod-template" . | nindent 4 }} + {{- with .Values.controller.updateStrategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/alloy/templates/controllers/statefulset.yaml b/charts/alloy/templates/controllers/statefulset.yaml new file mode 100644 index 0000000..a290834 --- /dev/null +++ b/charts/alloy/templates/controllers/statefulset.yaml @@ -0,0 +1,51 @@ +{{- if eq .Values.controller.type "statefulset" }} +{{- if .Values.enableStatefulSetAutoDeletePVC }} +{{- fail "Value 'enableStatefulSetAutoDeletePVC' should be nested inside 'controller' options." }} +{{- end }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + {{- with .Values.controller.extraAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if not .Values.controller.autoscaling.enabled }} + replicas: {{ .Values.controller.replicas }} + {{- end }} + {{- if .Values.controller.parallelRollout }} + podManagementPolicy: Parallel + {{- end }} + {{- if ge (int .Capabilities.KubeVersion.Minor) 22 }} + minReadySeconds: 10 + {{- end }} + serviceName: {{ include "alloy.fullname" . }} + selector: + matchLabels: + {{- include "alloy.selectorLabels" . | nindent 6 }} + template: + {{- include "alloy.pod-template" . | nindent 4 }} + {{- with .Values.controller.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.controller.volumeClaimTemplates }} + volumeClaimTemplates: + {{- range . }} + - {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} + {{- if and (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) (.Values.controller.enableStatefulSetAutoDeletePVC) }} + {{- /* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete + {{- end }} +{{- end }} diff --git a/charts/alloy/templates/extra-manifests.yaml b/charts/alloy/templates/extra-manifests.yaml new file mode 100644 index 0000000..a9bb3b6 --- /dev/null +++ b/charts/alloy/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/charts/alloy/templates/hpa.yaml b/charts/alloy/templates/hpa.yaml new file mode 100644 index 0000000..a2286c7 --- /dev/null +++ b/charts/alloy/templates/hpa.yaml @@ -0,0 +1,83 @@ +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if and (or (eq .Values.controller.type "deployment") (eq .Values.controller.type "statefulset" )) (or .Values.controller.autoscaling.horizontal.enabled .Values.controller.autoscaling.enabled) }} +{{ $autoscaling := .Values.controller.autoscaling }} +{{- if .Values.controller.autoscaling.horizontal.enabled }} +{{- $autoscaling = .Values.controller.autoscaling.horizontal }} +{{- end }} +{{- if (not (empty $autoscaling.targetMemoryUtilizationPercentage)) }} + {{- $_ := $values.resources.requests | required ".Values.alloy.resources.requests is required when using autoscaling." -}} + {{- $_ := $values.resources.requests.memory | required ".Values.alloy.resources.requests.memory is required when using autoscaling based on memory utilization." -}} + {{- $_ := .Values.configReloader.resources.requests | required ".Values.configReloader.resources.requests is required when using autoscaling." -}} + {{- $_ := .Values.configReloader.resources.requests.memory | required ".Values.configReloader.resources.requests.memory is required when using autoscaling based on memory utilization." -}} +{{- end}} +{{- if (not (empty $autoscaling.targetCPUUtilizationPercentage)) }} + {{- $_ := $values.resources.requests | required ".Values.alloy.resources.requests is required when using autoscaling." -}} + {{- $_ := $values.resources.requests.cpu | required ".Values.alloy.resources.requests.cpu is required when using autoscaling based on cpu utilization." -}} + {{- $_ := .Values.configReloader.resources.requests | required ".Values.configReloader.resources.requests is required when using autoscaling." -}} + {{- $_ := .Values.configReloader.resources.requests.cpu | required ".Values.configReloader.resources.requests.cpu is required when using autoscaling based on cpu utilization." -}} +{{- end}} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: availability +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: {{ .Values.controller.type }} + name: {{ include "alloy.fullname" . }} + {{- with $autoscaling }} + minReplicas: {{ .minReplicas }} + maxReplicas: {{ .maxReplicas }} + behavior: + {{- with .scaleDown }} + scaleDown: + {{- if .policies }} + policies: + {{- range .policies }} + - type: {{ .type }} + value: {{ .value }} + periodSeconds: {{ .periodSeconds }} + {{- end }} + selectPolicy: {{ .selectPolicy }} + {{- end }} + stabilizationWindowSeconds: {{ .stabilizationWindowSeconds }} + {{- end }} + {{- with .scaleUp }} + scaleUp: + {{- if .policies }} + policies: + {{- range .policies }} + - type: {{ .type }} + value: {{ .value }} + periodSeconds: {{ .periodSeconds }} + {{- end }} + selectPolicy: {{ .selectPolicy }} + {{- end }} + stabilizationWindowSeconds: {{ .stabilizationWindowSeconds }} + {{- end }} + metrics: + # Changing the order of the metrics will cause ArgoCD to go into a sync loop + # memory needs to be first. + # More info in: https://github.com/argoproj/argo-cd/issues/1079 + {{- with .targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} + {{- with .targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/alloy/templates/ingress.yaml b/charts/alloy/templates/ingress.yaml new file mode 100644 index 0000000..51a6e57 --- /dev/null +++ b/charts/alloy/templates/ingress.yaml @@ -0,0 +1,79 @@ +{{- if .Values.ingress.enabled -}} +{{- $ingressApiIsStable := eq (include "alloy.ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "alloy.ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "alloy.ingress.supportsPathType" .) "true" -}} +{{- $fullName := include "alloy.fullname" . -}} +{{- $servicePort := .Values.ingress.faroPort -}} +{{- $ingressPath := .Values.ingress.path -}} +{{- $ingressPathType := .Values.ingress.pathType -}} +{{- $extraPaths := .Values.ingress.extraPaths -}} +apiVersion: {{ include "alloy.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: networking + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingress.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ tpl $value $ | quote }} + {{- end }} + {{- end }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end -}} + {{- with .Values.ingress.tls }} + tls: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + rules: + {{- if .Values.ingress.hosts }} + {{- range .Values.ingress.hosts }} + - host: {{ tpl . $ }} + http: + paths: + {{- with $extraPaths }} + {{- toYaml . | nindent 10 }} + {{- end }} + - path: {{ $ingressPath }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end }} + {{- else }} + - http: + paths: + - backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- with $ingressPath }} + path: {{ . }} + {{- end }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + {{- end -}} +{{- end }} diff --git a/charts/alloy/templates/pdb.yaml b/charts/alloy/templates/pdb.yaml new file mode 100644 index 0000000..87b9db4 --- /dev/null +++ b/charts/alloy/templates/pdb.yaml @@ -0,0 +1,31 @@ +{{- if .Values.controller.podDisruptionBudget.enabled }} +{{- if eq .Values.controller.type "daemonset" }} +{{- fail "PDBs (Pod Disruption Budgets) are not intended for DaemonSets. Please use a different controller type." }} +{{- end }} + +{{- if and .Values.controller.podDisruptionBudget.minAvailable .Values.controller.podDisruptionBudget.maxUnavailable }} +{{- fail "Only one of minAvailable or maxUnavailable should be defined for PodDisruptionBudget" }} +{{- end }} + +{{- if not (or .Values.controller.podDisruptionBudget.minAvailable .Values.controller.podDisruptionBudget.maxUnavailable) }} +{{- fail "Either minAvailable or maxUnavailable must be defined for PodDisruptionBudget" }} +{{- end }} + +apiVersion: {{ include "alloy.controller.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "alloy.selectorLabels" . | nindent 6 }} + {{- if .Values.controller.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.controller.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.controller.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.controller.podDisruptionBudget.maxUnavailable }} + {{- end }} +{{- end }} diff --git a/charts/alloy/templates/rbac.yaml b/charts/alloy/templates/rbac.yaml new file mode 100644 index 0000000..38ccb0f --- /dev/null +++ b/charts/alloy/templates/rbac.yaml @@ -0,0 +1,112 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "alloy.fullname" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: rbac +rules: + # Rules which allow discovery.kubernetes to function. + - apiGroups: + - "" + - "discovery.k8s.io" + - "networking.k8s.io" + resources: + - endpoints + - endpointslices + - ingresses + - nodes + - nodes/proxy + - nodes/metrics + - pods + - services + verbs: + - get + - list + - watch + # Rules which allow loki.source.kubernetes and loki.source.podlogs to work. + - apiGroups: + - "" + resources: + - pods + - pods/log + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - "monitoring.grafana.com" + resources: + - podlogs + verbs: + - get + - list + - watch + # Rules which allow mimir.rules.kubernetes to work. + - apiGroups: ["monitoring.coreos.com"] + resources: + - prometheusrules + verbs: + - get + - list + - watch + - nonResourceURLs: + - /metrics + verbs: + - get + # Rules for prometheus.kubernetes.* + - apiGroups: ["monitoring.coreos.com"] + resources: + - podmonitors + - servicemonitors + - probes + - scrapeconfigs + verbs: + - get + - list + - watch + # Rules which allow eventhandler to work. + - apiGroups: + - "" + resources: + - events + verbs: + - get + - list + - watch + # needed for remote.kubernetes.* + - apiGroups: [""] + resources: + - "configmaps" + - "secrets" + verbs: + - get + - list + - watch + # needed for otelcol.processor.k8sattributes + - apiGroups: ["apps"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] + - apiGroups: ["extensions"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "alloy.fullname" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: rbac +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "alloy.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "alloy.serviceAccountName" . }} + namespace: {{ include "alloy.namespace" . }} +{{- end }} diff --git a/charts/alloy/templates/service.yaml b/charts/alloy/templates/service.yaml new file mode 100644 index 0000000..53f79b3 --- /dev/null +++ b/charts/alloy/templates/service.yaml @@ -0,0 +1,43 @@ +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if .Values.service.enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: networking + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- if .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + selector: + {{- include "alloy.selectorLabels" . | nindent 4 }} + {{- if semverCompare ">=1.26-0" .Capabilities.KubeVersion.Version }} + internalTrafficPolicy: {{.Values.service.internalTrafficPolicy}} + {{- end }} + ports: + - name: http-metrics + {{- if eq .Values.service.type "NodePort" }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + port: {{ $values.listenPort }} + targetPort: {{ $values.listenPort }} + protocol: "TCP" +{{- range $portMap := $values.extraPorts }} + - name: {{ $portMap.name }} + port: {{ $portMap.port }} + targetPort: {{ $portMap.targetPort }} + protocol: {{ coalesce $portMap.protocol "TCP" }} + {{- if not (empty $portMap.appProtocol) }} + # Useful for OpenShift clusters that want to expose Alloy ports externally + appProtocol: {{ $portMap.appProtocol }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/alloy/templates/serviceaccount.yaml b/charts/alloy/templates/serviceaccount.yaml new file mode 100644 index 0000000..55a6e91 --- /dev/null +++ b/charts/alloy/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "alloy.serviceAccountName" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: rbac + {{- with .Values.serviceAccount.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/alloy/templates/servicemonitor.yaml b/charts/alloy/templates/servicemonitor.yaml new file mode 100644 index 0000000..382b38a --- /dev/null +++ b/charts/alloy/templates/servicemonitor.yaml @@ -0,0 +1,37 @@ +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if and .Values.service.enabled .Values.serviceMonitor.enabled -}} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: metrics + {{- with .Values.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: http-metrics + scheme: {{ $values.listenScheme | lower }} + honorLabels: true + {{- if .Values.serviceMonitor.interval }} + interval: {{ .Values.serviceMonitor.interval }} + {{- end }} + {{- if .Values.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{ tpl (toYaml .Values.serviceMonitor.metricRelabelings | nindent 6) . }} + {{- end }} + {{- if .Values.serviceMonitor.relabelings }} + relabelings: + {{ tpl (toYaml .Values.serviceMonitor.relabelings | nindent 6) . }} + {{- end }} + {{- with .Values.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 6 }} + {{- end }} + selector: + matchLabels: + {{- include "alloy.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/alloy/templates/vpa.yaml b/charts/alloy/templates/vpa.yaml new file mode 100644 index 0000000..09877ee --- /dev/null +++ b/charts/alloy/templates/vpa.yaml @@ -0,0 +1,41 @@ +{{- if .Capabilities.APIVersions.Has "autoscaling.k8s.io/v1" -}} +{{- if .Values.controller.autoscaling.vertical.enabled -}} +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: {{ include "alloy.fullname" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: availability +spec: + {{- with .Values.controller.autoscaling.vertical }} + {{- with .recommenders }} + recommenders: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .resourcePolicy }} + resourcePolicy: + {{- with .containerPolicies }} + containerPolicies: + {{- range . }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + {{- end }} + {{- with .updatePolicy }} + updatePolicy: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + targetRef: + apiVersion: apps/v1 + {{- if eq .Values.controller.type "deployment" }} + kind: Deployment + {{- else if eq .Values.controller.type "statefulset" }} + kind: StatefulSet + {{- else }} + kind: DaemonSet + {{- end }} + name: {{ include "alloy.fullname" . }} +{{- end }} +{{- end }} diff --git a/charts/alloy/values.yaml b/charts/alloy/values.yaml new file mode 100644 index 0000000..8820a47 --- /dev/null +++ b/charts/alloy/values.yaml @@ -0,0 +1,463 @@ +# -- Overrides the chart's name. Used to change the infix in the resource names. +nameOverride: null + +# -- Overrides the chart's namespace. +namespaceOverride: null + +# -- Overrides the chart's computed fullname. Used to change the full prefix of +# resource names. +fullnameOverride: null + +## Global properties for image pulling override the values defined under `image.registry` and `configReloader.image.registry`. +## If you want to override only one image registry, use the specific fields but if you want to override them all, use `global.image.registry` +global: + image: + # -- Global image registry to use if it needs to be overridden for some specific use cases (e.g local registries, custom images, ...) + registry: "" + + # -- Optional set of global image pull secrets. + pullSecrets: [] + + # -- Security context to apply to the Grafana Alloy pod. + podSecurityContext: {} + +crds: + # -- Whether to install CRDs for monitoring. + create: true + +## Various Alloy settings. For backwards compatibility with the grafana-agent +## chart, this field may also be called "agent". Naming this field "agent" is +## deprecated and will be removed in a future release. +alloy: + configMap: + # -- Create a new ConfigMap for the config file. + create: true + # -- Content to assign to the new ConfigMap. This is passed into `tpl` allowing for templating from values. + content: '' + + # -- Name of existing ConfigMap to use. Used when create is false. + name: null + # -- Key in ConfigMap to get config from. + key: null + + clustering: + # -- Deploy Alloy in a cluster to allow for load distribution. + enabled: false + + # -- Name for the Alloy cluster. Used for differentiating between clusters. + name: "" + + # -- Name for the port used for clustering, useful if running inside an Istio Mesh + portName: http + + # -- Minimum stability level of components and behavior to enable. Must be + # one of "experimental", "public-preview", or "generally-available". + stabilityLevel: "generally-available" + + # -- Path to where Grafana Alloy stores data (for example, the Write-Ahead Log). + # By default, data is lost between reboots. + storagePath: /tmp/alloy + + # -- Address to listen for traffic on. 0.0.0.0 exposes the UI to other + # containers. + listenAddr: 0.0.0.0 + + # -- Port to listen for traffic on. + listenPort: 12345 + + # -- Scheme is needed for readiness probes. If enabling tls in your configs, set to "HTTPS" + listenScheme: HTTP + + # -- Base path where the UI is exposed. + uiPathPrefix: / + + # -- Enables sending Grafana Labs anonymous usage stats to help improve Grafana + # Alloy. + enableReporting: true + + # -- Extra environment variables to pass to the Alloy container. + extraEnv: [] + + # -- Maps all the keys on a ConfigMap or Secret as environment variables. https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#envfromsource-v1-core + envFrom: [] + + # -- Extra args to pass to `alloy run`: https://grafana.com/docs/alloy/latest/reference/cli/run/ + extraArgs: [] + + # -- Extra ports to expose on the Alloy container. + extraPorts: [] + # - name: "faro" + # port: 12347 + # targetPort: 12347 + # protocol: "TCP" + # appProtocol: "h2c" + + # -- Host aliases to add to the Alloy container. + hostAliases: [] + # - ip: "20.21.22.23" + # hostnames: + # - "company.grafana.net" + + mounts: + # -- Mount /var/log from the host into the container for log collection. + varlog: false + # -- Mount /var/lib/docker/containers from the host into the container for log + # collection. + dockercontainers: false + + # -- Extra volume mounts to add into the Grafana Alloy container. Does not + # affect the watch container. + extra: [] + + # -- Security context to apply to the Grafana Alloy container. + securityContext: {} + + # -- Resource requests and limits to apply to the Grafana Alloy container. + resources: {} + + # -- Set lifecycle hooks for the Grafana Alloy container. + lifecycle: {} + # preStop: + # exec: + # command: + # - /bin/sleep + # - "10" + + # -- Set livenessProbe for the Grafana Alloy container. + livenessProbe: {} + +image: + # -- Grafana Alloy image registry (defaults to docker.io) + registry: "docker.io" + # -- Grafana Alloy image repository. + repository: grafana/alloy + # -- (string) Grafana Alloy image tag. When empty, the Chart's appVersion is + # used. + tag: null + # -- Grafana Alloy image's SHA256 digest (either in format "sha256:XYZ" or "XYZ"). When set, will override `image.tag`. + digest: null + # -- Grafana Alloy image pull policy. + pullPolicy: IfNotPresent + # -- Optional set of image pull secrets. + pullSecrets: [] + +rbac: + # -- Whether to create RBAC resources for Alloy. + create: true + +serviceAccount: + # -- Whether to create a service account for the Grafana Alloy deployment. + create: true + # -- Additional labels to add to the created service account. + additionalLabels: {} + # -- Annotations to add to the created service account. + annotations: {} + # -- The name of the existing service account to use when + # serviceAccount.create is false. + name: null + # Whether the Alloy pod should automatically mount the service account token. + automountServiceAccountToken: true + +# Options for the extra controller used for config reloading. +configReloader: + # -- Enables automatically reloading when the Alloy config changes. + enabled: true + image: + # -- Config reloader image registry (defaults to docker.io) + registry: "quay.io" + # -- Repository to get config reloader image from. + repository: prometheus-operator/prometheus-config-reloader + # -- Tag of image to use for config reloading. + tag: v0.81.0 + # -- SHA256 digest of image to use for config reloading (either in format "sha256:XYZ" or "XYZ"). When set, will override `configReloader.image.tag` + digest: "" + # -- Override the args passed to the container. + customArgs: [] + # -- Resource requests and limits to apply to the config reloader container. + resources: + requests: + cpu: "10m" + memory: "50Mi" + # -- Security context to apply to the Grafana configReloader container. + securityContext: {} + +controller: + # -- Type of controller to use for deploying Grafana Alloy in the cluster. + # Must be one of 'daemonset', 'deployment', or 'statefulset'. + type: 'daemonset' + + # -- Number of pods to deploy. Ignored when controller.type is 'daemonset'. + replicas: 1 + + # -- Annotations to add to controller. + extraAnnotations: {} + + # -- Whether to deploy pods in parallel. Only used when controller.type is + # 'statefulset'. + parallelRollout: true + + # -- Configures Pods to use the host network. When set to true, the ports that will be used must be specified. + hostNetwork: false + + # -- Configures Pods to use the host PID namespace. + hostPID: false + + # -- Configures the DNS policy for the pod. https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy + dnsPolicy: ClusterFirst + + # -- Termination grace period in seconds for the Grafana Alloy pods. + # The default value used by Kubernetes if unspecifed is 30 seconds. + terminationGracePeriodSeconds: null + + # -- Update strategy for updating deployed Pods. + updateStrategy: {} + + # -- nodeSelector to apply to Grafana Alloy pods. + nodeSelector: {} + + # -- Tolerations to apply to Grafana Alloy pods. + tolerations: [] + + # -- Topology Spread Constraints to apply to Grafana Alloy pods. + topologySpreadConstraints: [] + + # -- priorityClassName to apply to Grafana Alloy pods. + priorityClassName: '' + + # -- Extra pod annotations to add. + podAnnotations: {} + + # -- Extra pod labels to add. + podLabels: {} + + # -- PodDisruptionBudget configuration. + podDisruptionBudget: + # -- Whether to create a PodDisruptionBudget for the controller. + enabled: false + # -- Minimum number of pods that must be available during a disruption. + # Note: Only one of minAvailable or maxUnavailable should be set. + minAvailable: null + # -- Maximum number of pods that can be unavailable during a disruption. + # Note: Only one of minAvailable or maxUnavailable should be set. + maxUnavailable: null + + # -- Whether to enable automatic deletion of stale PVCs due to a scale down operation, when controller.type is 'statefulset'. + enableStatefulSetAutoDeletePVC: false + + autoscaling: + # -- Creates a HorizontalPodAutoscaler for controller type deployment. + # Deprecated: Please use controller.autoscaling.horizontal instead + enabled: false + # -- The lower limit for the number of replicas to which the autoscaler can scale down. + minReplicas: 1 + # -- The upper limit for the number of replicas to which the autoscaler can scale up. + maxReplicas: 5 + # -- Average CPU utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetCPUUtilizationPercentage` to 0 will disable CPU scaling. + targetCPUUtilizationPercentage: 0 + # -- Average Memory utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetMemoryUtilizationPercentage` to 0 will disable Memory scaling. + targetMemoryUtilizationPercentage: 80 + + scaleDown: + # -- List of policies to determine the scale-down behavior. + policies: [] + # - type: Pods + # value: 4 + # periodSeconds: 60 + # -- Determines which of the provided scaling-down policies to apply if multiple are specified. + selectPolicy: Max + # -- The duration that the autoscaling mechanism should look back on to make decisions about scaling down. + stabilizationWindowSeconds: 300 + + scaleUp: + # -- List of policies to determine the scale-up behavior. + policies: [] + # - type: Pods + # value: 4 + # periodSeconds: 60 + # -- Determines which of the provided scaling-up policies to apply if multiple are specified. + selectPolicy: Max + # -- The duration that the autoscaling mechanism should look back on to make decisions about scaling up. + stabilizationWindowSeconds: 0 + + # -- Configures the Horizontal Pod Autoscaler for the controller. + horizontal: + # -- Enables the Horizontal Pod Autoscaler for the controller. + enabled: false + + # -- The lower limit for the number of replicas to which the autoscaler can scale down. + minReplicas: 1 + # -- The upper limit for the number of replicas to which the autoscaler can scale up. + maxReplicas: 5 + # -- Average CPU utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetCPUUtilizationPercentage` to 0 will disable CPU scaling. + targetCPUUtilizationPercentage: 0 + # -- Average Memory utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetMemoryUtilizationPercentage` to 0 will disable Memory scaling. + targetMemoryUtilizationPercentage: 80 + + scaleDown: + # -- List of policies to determine the scale-down behavior. + policies: [] + # - type: Pods + # value: 4 + # periodSeconds: 60 + # -- Determines which of the provided scaling-down policies to apply if multiple are specified. + selectPolicy: Max + # -- The duration that the autoscaling mechanism should look back on to make decisions about scaling down. + stabilizationWindowSeconds: 300 + + scaleUp: + # -- List of policies to determine the scale-up behavior. + policies: [] + # - type: Pods + # value: 4 + # periodSeconds: 60 + # -- Determines which of the provided scaling-up policies to apply if multiple are specified. + selectPolicy: Max + # -- The duration that the autoscaling mechanism should look back on to make decisions about scaling up. + stabilizationWindowSeconds: 0 + # -- Configures the Vertical Pod Autoscaler for the controller. + vertical: + # -- Enables the Vertical Pod Autoscaler for the controller. + enabled: false + + # -- List of recommenders to use for the Vertical Pod Autoscaler. + # Recommenders are responsible for generating recommendation for the object. + # List should be empty (then the default recommender will generate the recommendation) + # or contain exactly one recommender. + recommenders: [] + # recommenders: + # - name: custom-recommender-performance + + # -- Configures the resource policy for the Vertical Pod Autoscaler. + resourcePolicy: + # -- Configures the container policies for the Vertical Pod Autoscaler. + containerPolicies: + - containerName: alloy + # -- The controlled resources for the Vertical Pod Autoscaler. + controlledResources: + - cpu + - memory + # -- The controlled values for the Vertical Pod Autoscaler. Needs to be either RequestsOnly or RequestsAndLimits. + controlledValues: "RequestsAndLimits" + # -- The maximum allowed values for the pods. + maxAllowed: {} + # cpu: 200m + # memory: 100Mi + # -- Defines the min allowed resources for the pod + minAllowed: {} + # cpu: 200m + # memory: 100Mi + + # -- Configures the update policy for the Vertical Pod Autoscaler. + updatePolicy: + # -- Specifies minimal number of replicas which need to be alive for VPA Updater to attempt pod eviction + # minReplicas: 1 + # -- Specifies whether recommended updates are applied when a Pod is started and whether recommended updates + # are applied during the life of a Pod. Possible values are "Off", "Initial", "Recreate", and "Auto". + # updateMode: Auto + + # -- Affinity configuration for pods. + affinity: {} + + volumes: + # -- Extra volumes to add to the Grafana Alloy pod. + extra: [] + + # -- volumeClaimTemplates to add when controller.type is 'statefulset'. + volumeClaimTemplates: [] + + ## -- Additional init containers to run. + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + ## + initContainers: [] + + # -- Additional containers to run alongside the Alloy container and initContainers. + extraContainers: [] + +service: + # -- Creates a Service for the controller's pods. + enabled: true + # -- Service type + type: ClusterIP + # -- NodePort port. Only takes effect when `service.type: NodePort` + nodePort: 31128 + # -- Cluster IP, can be set to None, empty "" or an IP address + clusterIP: '' + # -- Value for internal traffic policy. 'Cluster' or 'Local' + internalTrafficPolicy: Cluster + annotations: {} + # cloud.google.com/load-balancer-type: Internal + +serviceMonitor: + enabled: false + # -- Additional labels for the service monitor. + additionalLabels: {} + # -- Scrape interval. If not set, the Prometheus default scrape interval is used. + interval: "" + # -- MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + # ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + # -- Customize tls parameters for the service monitor + tlsConfig: {} + + # -- RelabelConfigs to apply to samples before scraping + # ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace +ingress: + # -- Enables ingress for Alloy (Faro port) + enabled: false + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + # Values can be templated + annotations: + {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + labels: {} + path: / + faroPort: 12347 + + # pathType is only for k8s >= 1.1= + pathType: Prefix + + hosts: + - chart-example.local + ## Extra paths to prepend to every host configuration. This is useful when working with annotation based services. + extraPaths: [] + # - path: /* + # backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + ## Or for k8s > 1.19 + # - path: /* + # pathType: Prefix + # backend: + # service: + # name: ssl-redirect + # port: + # name: use-annotation + + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +# -- Extra k8s manifests to deploy +extraObjects: [] +# - apiVersion: v1 +# kind: Secret +# metadata: +# name: grafana-cloud +# stringData: +# PROMETHEUS_HOST: 'https://prometheus-us-central1.grafana.net/api/prom/push' +# PROMETHEUS_USERNAME: '123456' diff --git a/charts/localpv-provisioner/Chart.yaml b/charts/localpv-provisioner/Chart.yaml new file mode 100644 index 0000000..bd6066e --- /dev/null +++ b/charts/localpv-provisioner/Chart.yaml @@ -0,0 +1,15 @@ +apiVersion: v2 +appVersion: 4.4.0 +description: Helm chart for OpenEBS Dynamic Local PV. For instructions to install + OpenEBS Dynamic Local PV using helm chart, refer to https://openebs.github.io/dynamic-localpv-provisioner/. +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- storage +- local +- dynamic-localpv +name: localpv-provisioner +sources: +- https://github.com/openebs/dynamic-localpv-provisioner +type: application +version: 4.4.0 diff --git a/charts/localpv-provisioner/README.md b/charts/localpv-provisioner/README.md new file mode 100644 index 0000000..2fb6805 --- /dev/null +++ b/charts/localpv-provisioner/README.md @@ -0,0 +1,117 @@ +# OpenEBS LocalPV Provisioner + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Chart Lint and Test](https://github.com/openebs/dynamic-localpv-provisioner/workflows/Chart%20Lint%20and%20Test/badge.svg) +![Release Charts](https://github.com/openebs/dynamic-localpv-provisioner/workflows/Release%20Charts/badge.svg?branch=develop) + +A Helm chart for openebs dynamic localpv provisioner. This chart bootstraps OpenEBS Dynamic LocalPV provisioner deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + + +**Homepage:** + +## Get Repo Info + +```console +helm repo add openebs-localpv https://openebs.github.io/dynamic-localpv-provisioner +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +Please visit the [link](https://openebs.github.io/dynamic-localpv-provisioner/) for install instructions via helm3. + +```console +# Helm +helm install [RELEASE_NAME] openebs-localpv/localpv-provisioner --namespace [NAMESPACE] --create-namespace +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +# Helm +helm uninstall [RELEASE_NAME] --namespace [NAMESPACE] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +# Helm +helm upgrade [RELEASE_NAME] [CHART] --install --namespace [NAMESPACE] +``` + + +## Configuration + +The following table lists the configurable parameters of the OpenEBS Dynamic LocalPV Provisioner chart and their default values. + +You can modify different parameters by specifying the desired value in the `helm install` command by using the `--set` and/or the `--set-string` flag(s). + +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace +``` + +Sample command to install the provisioner with nodeAffinityLabels "openebs.io/node-affinity-key-1" and "openebs.io/node-affinity-key-2" on the hostpath StorageClass: +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace \ + --set-string hostpathClass.nodeAffinityLabels="{openebs.io/node-affinity-key-1,openebs.io/node-affinity-key-2}" +``` + +| Parameter | Description | Default | +| ------------------------------------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------| +| `analytics.enabled` | Enable sending stats to Google Analytics | `true` | +| `analytics.pingInterval` | Duration(hours) between sending ping stat | `24h` | +| `extraLabels` | Additional labels to add to all chart resources | `{}` | +| `global.imageRegistry` | Default image registry, overridden by localpv.image.registry and helperPod.image.registry | `""` | +| `helperPod.image.registry` | Registry for helper image | `""` | +| `helperPod.image.repository` | Image for helper pod | `"openebs/linux-utils"` | +| `helperPod.image.pullPolicy` | Pull policy for helper pod | `"IfNotPresent"` | +| `helperPod.image.tag` | Image tag for helper image | `4.2.0` | +| `hostpathClass.basePath` | BasePath for openebs-hostpath StorageClass | `"/var/openebs/local"` | +| `hostpathClass.enabled` | Enables creation of default Hostpath StorageClass | `true` | +| `hostpathClass.isDefaultClass` | Make openebs-hostpath the default StorageClass | `"false"` | +| `hostpathClass.nodeAffinityLabels` | Custom node label(or labels) key to uniquely identify nodes. `kubernetes.io/hostname` is the default label key for node selection. | `[]` | +| `hostpathClass.xfsQuota.enabled` | Enable XFS Quota (requires XFS filesystem) | `false` | +| `hostpathClass.ext4Quota.enabled` | Enable EXT4 Quota (requires EXT4 filesystem) | `false` | +| `hostpathClass.reclaimPolicy` | ReclaimPolicy for Hostpath PVs | `"Delete"` | +| `imagePullSecrets` | Provides image pull secrect | `""` | +| `localpv.enabled` | Enable LocalPV Provisioner | `true` | +| `localpv.image.registry` | Registry for LocalPV Provisioner image | `""` | +| `localpv.image.repository` | Image repository for LocalPV Provisioner | `openebs/localpv-provisioner` | +| `localpv.image.pullPolicy` | Image pull policy for LocalPV Provisioner | `IfNotPresent` | +| `localpv.image.tag` | Image tag for LocalPV Provisioner | `4.4.0` | +| `localpv.updateStrategy.type` | Update strategy for LocalPV Provisioner | `RollingUpdate` | +| `localpv.annotations` | Annotations for LocalPV Provisioner metadata | `""` | +| `localpv.podAnnotations` | Annotations for LocalPV Provisioner pods metadata | `""` | +| `localpv.privileged` | Run LocalPV Provisioner with extra privileges | `true` | +| `localpv.resources` | Resource and request and limit for containers | `""` | +| `localpv.podLabels` | Appends labels to the pods | `""` | +| `localpv.nodeSelector` | Nodeselector for LocalPV Provisioner pods | `""` | +| `localpv.tolerations` | LocalPV Provisioner pod toleration values | `""` | +| `localpv.securityContext` | Seurity context for container | `""` | +| `localpv.healthCheck.initialDelaySeconds` | Delay before liveness probe is initiated | `30` | +| `localpv.healthCheck.periodSeconds` | How often to perform the liveness probe | `60` | +| `localpv.replicas` | No. of LocalPV Provisioner replica | `1` | +| `localpv.enableLeaderElection` | Enable leader election | `true` | +| `localpv.affinity` | LocalPV Provisioner pod affinity | `{}` | +| `localpv.priorityClassName` | Sets priorityClassName in pod | `""` | +| `rbac.create` | Enable RBAC Resources | `true` | +| `rbac.pspEnabled` | Create pod security policy resources | `false` | + + +A YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml --namespace openebs openebs-localpv/localpv-provisioner +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/charts/localpv-provisioner/templates/NOTES.txt b/charts/localpv-provisioner/templates/NOTES.txt new file mode 100644 index 0000000..54ab551 --- /dev/null +++ b/charts/localpv-provisioner/templates/NOTES.txt @@ -0,0 +1,9 @@ +The OpenEBS Dynamic LocalPV Provisioner has been installed. +Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +Get started with the Dynamic LocalPV Provisioner Quickstart guide at: +https://github.com/openebs/dynamic-localpv-provisioner/blob/develop/docs/quickstart.md + +For more information, visit our Slack at https://kubernetes.slack.com/messages/openebs or view +the OpenEBS documentation online at https://openebs.io/docs diff --git a/charts/localpv-provisioner/templates/_helpers.tpl b/charts/localpv-provisioner/templates/_helpers.tpl new file mode 100644 index 0000000..d49f162 --- /dev/null +++ b/charts/localpv-provisioner/templates/_helpers.tpl @@ -0,0 +1,91 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "localpv.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified localpv provisioner 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 "localpv.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "localpv.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Meta labels +*/}} +{{- define "localpv.common.metaLabels" -}} +chart: {{ template "localpv.chart" . }} +heritage: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "localpv.selectorLabels" -}} +app: {{ template "localpv.name" . }} +release: {{ .Release.Name }} +component: {{ .Values.localpv.name | quote }} +{{- end -}} + +{{/* +Component labels +*/}} +{{- define "localpv.componentLabels" -}} +openebs.io/component-name: openebs-{{ .Values.localpv.name }} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "localpv.labels" -}} +{{ include "localpv.common.metaLabels" . }} +{{ include "localpv.selectorLabels" . }} +{{ include "localpv.componentLabels" . }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "localpv.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "localpv.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Creates the tolerations based on the global tolerations, with early eviction +Usage: +{{ include "tolerations_with_early_eviction" . }} +*/}} +{{- define "tolerations_with_early_eviction" -}} +{{- if .Values.earlyEvictionTolerations }} + {{- toYaml .Values.earlyEvictionTolerations | nindent 8 }} +{{- end }} +{{- if .Values.localpv.tolerations }} + {{- toYaml .Values.localpv.tolerations | nindent 8 }} +{{- end }} +{{- end }} diff --git a/charts/localpv-provisioner/templates/deployment.yaml b/charts/localpv-provisioner/templates/deployment.yaml new file mode 100644 index 0000000..c631cf0 --- /dev/null +++ b/charts/localpv-provisioner/templates/deployment.yaml @@ -0,0 +1,133 @@ +{{- if .Values.localpv.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.localpv.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + {{- include "localpv.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.localpv.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 8 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 8 }} + {{- end }} + {{- with .Values.localpv.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.loggingLabels}} + {{ toYaml . | nindent 8 -}} + {{- end}} + spec: + {{- if .Values.localpv.priorityClassName }} + priorityClassName: {{ tpl .Values.localpv.priorityClassName . }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "localpv.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ template "localpv.fullname" . }} + image: "{{ with .Values.localpv.image.registry | default .Values.global.imageRegistry | trimSuffix "/" }}{{ . }}/{{ end }}{{ .Values.localpv.image.repository }}:{{ .Values.localpv.image.tag }}" + imagePullPolicy: {{ .Values.localpv.image.pullPolicy }} + resources: +{{ toYaml .Values.localpv.resources | indent 10 }} + env: + # OPENEBS_IO_K8S_MASTER enables openebs provisioner to connect to K8s + # based on this address. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_K8S_MASTER + # value: "http://10.128.0.12:8080" + # OPENEBS_IO_KUBE_CONFIG enables openebs provisioner to connect to K8s + # based on this config. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_KUBE_CONFIG + # value: "/home/ubuntu/.kube/config" + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + # OPENEBS_SERVICE_ACCOUNT provides the service account of this pod as + # environment variable + - name: OPENEBS_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + # OPENEBS_IO_BASE_PATH is the environment variable that provides the + # default base path on the node where host-path PVs will be provisioned. + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + {{- if .Values.analytics.gaId }} + - name: GA_ID + value: {{ .Values.analytics.gaId | quote }} + {{- end }} + {{- if .Values.analytics.gaKey }} + - name: GA_KEY + value: {{ .Values.analytics.gaKey | quote }} + {{- end }} + - name: OPENEBS_IO_BASE_PATH + value: "{{ .Values.localpv.basePath }}" + - name: OPENEBS_IO_HELPER_IMAGE + value: "{{ with .Values.helperPod.image.registry | default .Values.global.imageRegistry | trimSuffix "/" }}{{ . }}/{{ end }}{{ .Values.helperPod.image.repository }}:{{ .Values.helperPod.image.tag }}" + - name: OPENEBS_IO_HELPER_POD_HOST_NETWORK + value: "{{ .Values.helperPod.hostNetwork }}" + - name: OPENEBS_IO_INSTALLER_TYPE + value: "localpv-charts-helm" + # LEADER_ELECTION_ENABLED is used to enable/disable leader election. By default + # leader election is enabled. + - name: LEADER_ELECTION_ENABLED + value: "{{ .Values.localpv.enableLeaderElection }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $index, $secret := .Values.imagePullSecrets}}{{if $index}},{{end}}{{ $secret.name }}{{- end}}" +{{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can't be used here with pgrep (>15 chars).A regular expression + # that matches the entire command name has to specified. + # Anchor `^` : matches any string that starts with `provisioner-loc` + # `.*`: matches any string that has `provisioner-loc` followed by zero or more char + livenessProbe: + exec: + command: + - sh + - -c + - test `pgrep -c "^provisioner-loc.*"` = 1 + initialDelaySeconds: {{ .Values.localpv.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.localpv.healthCheck.periodSeconds }} +{{- if .Values.localpv.nodeSelector }} + nodeSelector: +{{ toYaml .Values.localpv.nodeSelector | indent 8 }} +{{- end }} +{{- if $tolerations := include "tolerations_with_early_eviction" . }} + tolerations: {{ $tolerations }} +{{- end }} +{{- if .Values.localpv.affinity }} + affinity: +{{ toYaml .Values.localpv.affinity | indent 8 }} +{{- end }} +{{- end }} diff --git a/charts/localpv-provisioner/templates/hostpath-class.yaml b/charts/localpv-provisioner/templates/hostpath-class.yaml new file mode 100644 index 0000000..7c5be71 --- /dev/null +++ b/charts/localpv-provisioner/templates/hostpath-class.yaml @@ -0,0 +1,43 @@ +{{- if .Values.hostpathClass.enabled }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ tpl (.Values.hostpathClass.name) .}} + annotations: + openebs.io/cas-type: local + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" +{{- if or .Values.localpv.basePath .Values.hostpathClass.basePath }} + - name: BasePath + value: {{ tpl (.Values.hostpathClass.basePath | default .Values.localpv.basePath | quote) . }} +{{- end }} +{{- if .Values.hostpathClass.nodeAffinityLabels }} + - name: NodeAffinityLabels + list: +{{ toYaml .Values.hostpathClass.nodeAffinityLabels | indent 10 }} +{{- end }} +{{- if .Values.hostpathClass.xfsQuota.enabled }} + - name: XFSQuota + enabled: "{{ .Values.hostpathClass.xfsQuota.enabled }}" + data: + softLimitGrace: "{{ .Values.hostpathClass.xfsQuota.softLimitGrace }}" + hardLimitGrace: "{{ .Values.hostpathClass.xfsQuota.hardLimitGrace }}" +{{- end }} +{{- if .Values.hostpathClass.ext4Quota.enabled }} + - name: EXT4Quota + enabled: "{{ .Values.hostpathClass.ext4Quota.enabled }}" + data: + softLimitGrace: "{{ .Values.hostpathClass.ext4Quota.softLimitGrace }}" + hardLimitGrace: "{{ .Values.hostpathClass.ext4Quota.hardLimitGrace }}" +{{- end }} +{{- if .Values.hostpathClass.isDefaultClass }} + storageclass.kubernetes.io/is-default-class: "true" +{{- end }} +{{- if .Values.extraLabels }} + labels: {{- toYaml .Values.extraLabels | nindent 4 -}} +{{- end }} +provisioner: openebs.io/local +volumeBindingMode: WaitForFirstConsumer +reclaimPolicy: {{ .Values.hostpathClass.reclaimPolicy }} +{{- end }} diff --git a/charts/localpv-provisioner/templates/psp.yaml b/charts/localpv-provisioner/templates/psp.yaml new file mode 100644 index 0000000..ed97e28 --- /dev/null +++ b/charts/localpv-provisioner/templates/psp.yaml @@ -0,0 +1,33 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} +spec: + privileged: {{ .Values.localpv.privileged }} + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: true + hostPorts: + - min: 0 + max: 65535 + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/charts/localpv-provisioner/templates/rbac.yaml b/charts/localpv-provisioner/templates/rbac.yaml new file mode 100644 index 0000000..aeeed85 --- /dev/null +++ b/charts/localpv-provisioner/templates/rbac.yaml @@ -0,0 +1,117 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "localpv.serviceAccountName" . }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- if .Values.rbac.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} +rules: +- apiGroups: ["*"] + resources: ["nodes"] + verbs: ["get", "list", "watch"] +- apiGroups: ["*"] + resources: ["namespaces", "pods", "events", "endpoints"] + verbs: ["*"] +- apiGroups: ["*"] + resources: ["resourcequotas", "limitranges"] + verbs: ["list", "watch"] +- apiGroups: ["*"] + resources: ["storageclasses", "persistentvolumeclaims", "persistentvolumes"] + verbs: ["*"] +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: [ "get", "list", "create", "update", "delete", "patch"] +- apiGroups: ["openebs.io"] + resources: [ "*"] + verbs: ["*" ] +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "create", "update"] +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "localpv.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "localpv.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- if .Values.rbac.pspEnabled }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "localpv.fullname" . }}-psp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "localpv.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "localpv.serviceAccountName" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/charts/localpv-provisioner/values.yaml b/charts/localpv-provisioner/values.yaml new file mode 100644 index 0000000..3528c5c --- /dev/null +++ b/charts/localpv-provisioner/values.yaml @@ -0,0 +1,144 @@ +# Default values for localpv. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +global: + # Used as default image registry, values supplied by localpv.image.registry + # and helperPod.image.registry override this value. + imageRegistry: "docker.io" + +rbac: + # rbac.create: `true` if rbac resources should be created + create: true + # rbac.pspEnabled: `true` if PodSecurityPolicy resources should be created + pspEnabled: false + +earlyEvictionTolerations: + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 5 + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 5 + +localpv: + name: localpv-provisioner + enabled: true + image: + registry: "" + repository: openebs/provisioner-localpv + tag: 4.4.0 + pullPolicy: IfNotPresent + updateStrategy: + type: RollingUpdate + # If set to false, containers created by the localpv provisioner will run without extra privileges. + privileged: true + annotations: {} + podAnnotations: {} + ## Labels to be added to localpv provisioner deployment pods + podLabels: + name: openebs-localpv-provisioner + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + replicas: 1 + enableLeaderElection: true + basePath: "/var/openebs/local" + resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + nodeSelector: {} + tolerations: [] + affinity: {} + securityContext: {} + ## Sets priorityClassName in pod + priorityClassName: "" + +imagePullSecrets: +# - name: img-pull-secret +podSecurityContext: {} +# fsGroup: 2000 + +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: + +hostpathClass: + # Name of the default hostpath StorageClass + name: openebs-hostpath + # If true, enables creation of the openebs-hostpath StorageClass + enabled: true + # Available reclaim policies: Delete/Retain, defaults: Delete. + reclaimPolicy: Delete + # If true, sets the openebs-hostpath StorageClass as the default StorageClass + isDefaultClass: false + # Path on the host where local volumes of this storage class are mounted under. + # NOTE: If not specified, this defaults to the value of localpv.basePath. + basePath: "" + # Custom node affinity label(s) for example "openebs.io/node-affinity-value" + # that will be used instead of hostnames + # This helps in cases where the hostname changes when the node is removed and + # added back with the disks still intact. + # Example: + # nodeAffinityLabels: + # - "openebs.io/node-affinity-key-1" + # - "openebs.io/node-affinity-key-2" + nodeAffinityLabels: [] + # Prerequisite: XFS Quota requires an XFS filesystem mounted with + # the 'pquota' or 'prjquota' mount option. + xfsQuota: + # If true, enables XFS project quota + enabled: false + # Detailed configuration options for XFS project quota. + # If XFS Quota is enabled with the default values, the usage limit + # is set at the storage capacity specified in the PVC. + softLimitGrace: "0%" + hardLimitGrace: "0%" + # Prerequisite: EXT4 Quota requires an EXT4 filesystem mounted with + # the 'prjquota' mount option. + ext4Quota: + # If true, enables XFS project quota + enabled: false + # Detailed configuration options for EXT4 project quota. + # If EXT4 Quota is enabled with the default values, the usage limit + # is set at the storage capacity specified in the PVC. + softLimitGrace: "0%" + hardLimitGrace: "0%" + +helperPod: + image: + registry: "" + repository: openebs/linux-utils + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 4.3.0 + hostNetwork: false + +# Additional labels to add to all chart resources +extraLabels: {} + +loggingLabels: + openebs.io/logging: "true" + +analytics: + enabled: true + # Specify in hours the duration after which a ping event needs to be sent. + pingInterval: "24h" diff --git a/charts/loki/.helmignore b/charts/loki/.helmignore new file mode 100644 index 0000000..6d90723 --- /dev/null +++ b/charts/loki/.helmignore @@ -0,0 +1,32 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ + +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ + +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ + +# Other +doc.yaml +README.tpl +README.md.gotmpl +ci +CHANGELOG.md diff --git a/charts/loki/Chart.lock b/charts/loki/Chart.lock new file mode 100644 index 0000000..1cc42f7 --- /dev/null +++ b/charts/loki/Chart.lock @@ -0,0 +1,12 @@ +dependencies: +- name: minio + repository: https://charts.min.io/ + version: 5.4.0 +- name: grafana-agent-operator + repository: https://grafana.github.io/helm-charts + version: 0.5.1 +- name: rollout-operator + repository: https://grafana.github.io/helm-charts + version: 0.24.0 +digest: sha256:beb08aeb31a1fa6b88c326b307c9960ca5fc5032892f7acd5deae6b859884638 +generated: "2025-02-26T01:09:19.861074559Z" diff --git a/charts/loki/Chart.yaml b/charts/loki/Chart.yaml new file mode 100644 index 0000000..9f43ee6 --- /dev/null +++ b/charts/loki/Chart.yaml @@ -0,0 +1,32 @@ +apiVersion: v2 +appVersion: 3.4.2 +dependencies: +- alias: minio + condition: minio.enabled + name: minio + repository: https://charts.min.io/ + version: 5.4.0 +- alias: grafana-agent-operator + condition: monitoring.selfMonitoring.grafanaAgent.installOperator + name: grafana-agent-operator + repository: https://grafana.github.io/helm-charts + version: 0.5.1 +- alias: rollout_operator + condition: rollout_operator.enabled + name: rollout-operator + repository: https://grafana.github.io/helm-charts + version: 0.24.0 +description: Helm chart for Grafana Loki and Grafana Enterprise Logs supporting monolithic, + simple scalable, and microservices modes. +home: https://grafana.github.io/helm-charts +icon: https://grafana.com/docs/loki/latest/logo_and_name.png +maintainers: +- name: trevorwhitney +- name: jeschkies +name: loki +sources: +- https://github.com/grafana/loki +- https://grafana.com/oss/loki/ +- https://grafana.com/docs/loki/latest/ +type: application +version: 6.29.0 diff --git a/charts/loki/Makefile b/charts/loki/Makefile new file mode 100644 index 0000000..373086a --- /dev/null +++ b/charts/loki/Makefile @@ -0,0 +1,84 @@ +.DEFAULT_GOAL := all +.PHONY: lint lint-yaml install-distributed install-single-binary uninstall update-chart update + +# Optional image override, example: make install-distributed IMAGE=grafana/loki:2.9.0 +IMAGE ?= + +# Optional helm arguments, example: make install-distributed ARGS="--set loki.auth.enabled=true" +ARGS ?= + +# Default arguments to disable affinity for testing +DEFAULT_ARGS = --set gateway.affinity=null \ + --set ingester.affinity=null \ + --set distributor.affinity=null \ + --set querier.affinity=null \ + --set queryFrontend.affinity=null \ + --set queryScheduler.affinity=null \ + --set indexGateway.affinity=null \ + --set compactor.affinity=null \ + --set ruler.affinity=null \ + --set backend.affinity=null \ + --set read.affinity=null \ + --set write.affinity=null \ + --set singleBinary.affinity=null \ + --set memcachedChunks.affinity=null \ + --set memcachedFrontend.affinity=null \ + --set memcachedIndexQueries.affinity=null \ + --set memcachedMetadata.affinity=null \ + --set memcachedResults.affinity=null \ + --set global.podAntiAffinity=null \ + --set global.podAntiAffinityTopologyKey=null + +# Generate image override flag if IMAGE is provided +IMAGE_FLAG = $(if $(IMAGE),\ + $(eval PARTS=$(subst :, ,$(IMAGE)))\ + $(eval REPO_PARTS=$(subst /, ,$(word 1,$(PARTS))))\ + $(eval TAG=$(word 2,$(PARTS)))\ + $(eval REPO_COUNT=$(words $(REPO_PARTS)))\ + $(if $(filter 3,$(REPO_COUNT)),\ + --set loki.image.registry=$(word 1,$(REPO_PARTS))/$(word 2,$(REPO_PARTS)) --set loki.image.repository=$(word 3,$(REPO_PARTS)),\ + --set loki.image.registry=$(word 1,$(REPO_PARTS)) --set loki.image.repository=$(word 2,$(REPO_PARTS))\ + ) --set loki.image.tag=$(TAG),) + +lint: lint-yaml + +lint-yaml: + yamllint -c $(CURDIR)/src/.yamllint.yaml $(CURDIR)/src + +# Helm chart installation targets +install-distributed: + helm upgrade --install loki . \ + -f distributed-values.yaml \ + --create-namespace \ + --namespace loki \ + $(DEFAULT_ARGS) \ + $(IMAGE_FLAG) \ + $(ARGS) + +install-single-binary: + helm upgrade --install loki . \ + -f single-binary-values.yaml \ + --create-namespace \ + --namespace loki \ + $(DEFAULT_ARGS) \ + $(IMAGE_FLAG) \ + $(ARGS) + +# Uninstall Loki helm release and optionally delete the namespace +uninstall: + helm uninstall loki --namespace loki + kubectl delete namespace loki --ignore-not-found + +# Update Helm chart dependencies +update-chart: + helm dependency update . + +# Update existing installation with latest changes +update: + @if [ "$$(helm get values loki -n loki -o yaml | grep "deploymentMode: Distributed")" ]; then \ + echo "Updating distributed deployment..."; \ + helm upgrade loki . -f distributed-values.yaml --namespace loki $(DEFAULT_ARGS) $(IMAGE_FLAG) $(ARGS); \ + else \ + echo "Updating single binary deployment..."; \ + helm upgrade loki . -f single-binary-values.yaml --namespace loki $(DEFAULT_ARGS) $(IMAGE_FLAG) $(ARGS); \ + fi diff --git a/charts/loki/README.md b/charts/loki/README.md new file mode 100644 index 0000000..5dcf910 --- /dev/null +++ b/charts/loki/README.md @@ -0,0 +1,65 @@ +# loki + +![Version: 6.29.0](https://img.shields.io/badge/Version-6.29.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 3.4.2](https://img.shields.io/badge/AppVersion-3.4.2-informational?style=flat-square) + +Helm chart for Grafana Loki and Grafana Enterprise Logs supporting monolithic, simple scalable, and microservices modes. + +## Source Code + +* +* +* + +## Requirements + +| Repository | Name | Version | +|------------|------|---------| +| https://charts.min.io/ | minio(minio) | 5.4.0 | +| https://grafana.github.io/helm-charts | grafana-agent-operator(grafana-agent-operator) | 0.5.1 | +| https://grafana.github.io/helm-charts | rollout_operator(rollout-operator) | 0.24.0 | + +Find more information in the Loki Helm Chart [documentation](https://grafana.com/docs/loki/next/installation/helm). + +## Contributing and releasing + +If you made any changes to the [Chart.yaml](https://github.com/grafana/loki/blob/main/production/helm/loki/Chart.yaml) or [values.yaml](https://github.com/grafana/loki/blob/main/production/helm/loki/values.yaml) run `make helm-docs` from the root of the repository to update the documentation and commit the changed files. + +Futhermore, please add an entry to the [CHANGELOG.md](./CHANGELOG.md) file about what you changed. This file has a header that looks like this: + +``` +[//]: # ( : do not remove this line. This locator is used by the CI pipeline to automatically create a changelog entry for each new Loki release. Add other chart versions and respective changelog entries bellow this line.) +```` + +Place your changes as a bulleted list below this header. The helm chart is automatically released once a week, at which point the `CHANGELOG.md` file will be updated to reflect the release of all changes between this header the the header of the previous version as the changes for that weeks release. For example, if the weekly release will be `1.21.0`, and the `CHANGELOG.md` file has the following entries: + +``` +[//]: # ( : do not remove this line. This locator is used by the CI pipeline to automatically create a changelog entry for each new Loki release. Add other chart versions and respective changelog entries bellow this line.) + +- [CHANGE] Changed the thing +- [FEATURE] Cool new feature + +## 1.20.0 + +- [BUGFIX] Fixed the bug +``` + +Then the weekly release will create a `CHANGELOG.md` with the following content: +``` +[//]: # ( : do not remove this line. This locator is used by the CI pipeline to automatically create a changelog entry for each new Loki release. Add other chart versions and respective changelog entries bellow this line.) + +## 1.21.0 + +- [CHANGE] Changed the thing +- [FEATURE] Cool new feature + +## 1.20.0 + +- [BUGFIX] Fixed the bug +``` + +#### Versioning + +Normally contributors need _not_ bump the version nor update the [CHANGELOG.md](https://github.com/grafana/loki/blob/main/production/helm/loki/CHANGELOG.md). A new version of the Chart will follow this cadence: +- Automatic weekly releases +- Releases that coincide with Loki/GEL releases +- Manual releases when necessary (ie. to address a CVE or critical bug) diff --git a/charts/loki/charts/grafana-agent-operator/.helmignore b/charts/loki/charts/grafana-agent-operator/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/loki/charts/grafana-agent-operator/Chart.yaml b/charts/loki/charts/grafana-agent-operator/Chart.yaml new file mode 100644 index 0000000..ef2b820 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +appVersion: 0.44.2 +description: A Helm chart for Grafana Agent Operator +home: https://grafana.com/docs/agent/v0.44/ +icon: https://raw.githubusercontent.com/grafana/agent/v0.44.2/docs/sources/assets/logo_and_name.png +maintainers: +- email: grafana-agent-team@googlegroups.com + name: Grafana Agent Team +name: grafana-agent-operator +sources: +- https://github.com/grafana/agent/tree/v0.44.2/static/operator +type: application +version: 0.5.1 diff --git a/charts/loki/charts/grafana-agent-operator/README.md b/charts/loki/charts/grafana-agent-operator/README.md new file mode 100644 index 0000000..57589a7 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/README.md @@ -0,0 +1,82 @@ +# grafana-agent-operator + +![Version: 0.5.1](https://img.shields.io/badge/Version-0.5.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.44.2](https://img.shields.io/badge/AppVersion-0.44.2-informational?style=flat-square) + +A Helm chart for Grafana Agent Operator + +⚠️ **Please create issues relating to this Helm chart in the [Agent](https://github.com/grafana/agent/issues) repo.** + +## Source Code + +* + +Note that this chart does not provision custom resources like `GrafanaAgent` and `MetricsInstance` (formerly `PrometheusInstance`) or any `*Monitor` resources. + +To learn how to deploy these resources, please see Grafana's [Agent Operator getting started guide](https://grafana.com/docs/agent/latest/operator/getting-started/). + +## CRDs + +The CRDs are synced into this chart manually (for now) from the Grafana Agent [GitHub repo](https://github.com/grafana/agent/tree/main/operations/agent-static-operator/crds). To learn more about how Helm manages CRDs, please see [Custom Resource Definitions](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/) from the Helm docs. + +## Get Repo Info + +```console +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release grafana/grafana-agent-operator +``` + +## Uninstalling the Chart + +To uninstall/delete the my-release deployment: + +```console +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Upgrading an existing Release to a new major version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an incompatible breaking change needing manual actions. Until this chart's version reaches `v1.0`, there are no promises of backwards compatibility. + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | Pod affinity configuration | +| annotations | object | `{}` | Annotations for the Deployment | +| containerSecurityContext | object | `{}` | Container security context (allowPrivilegeEscalation, etc.) | +| extraArgs | list | `[]` | List of additional cli arguments to configure agent-operator (example: `--log.level`) | +| fullnameOverride | string | `""` | Overrides the chart's computed fullname | +| global.commonLabels | object | `{}` | Common labels for all object directly managed by this chart. | +| hostAliases | list | `[]` | hostAliases to add | +| image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | +| image.pullSecrets | list | `[]` | Image pull secrets | +| image.registry | string | `"docker.io"` | Image registry | +| image.repository | string | `"grafana/agent-operator"` | Image repo | +| image.tag | string | `"v0.44.2"` | Image tag | +| kubeletService | object | `{"namespace":"default","serviceName":"kubelet"}` | If both are set, Agent Operator will create and maintain a service for scraping kubelets https://grafana.com/docs/agent/latest/operator/getting-started/#monitor-kubelets | +| nameOverride | string | `""` | Overrides the chart's name | +| nodeSelector | object | `{}` | nodeSelector configuration | +| podAnnotations | object | `{}` | Annotations for the Deployment Pods | +| podLabels | object | `{}` | Annotations for the Deployment Pods | +| podSecurityContext | object | `{}` | Pod security context (runAsUser, etc.) | +| rbac.create | bool | `true` | Toggle to create ClusterRole and ClusterRoleBinding | +| rbac.podSecurityPolicyName | string | `""` | Name of a PodSecurityPolicy to use in the ClusterRole. If unset, no PodSecurityPolicy is used. | +| resources | object | `{}` | Resource limits and requests config | +| serviceAccount.create | bool | `true` | Toggle to create ServiceAccount | +| serviceAccount.name | string | `nil` | Service account name | +| test.image.registry | string | `"docker.io"` | Test image registry | +| test.image.repository | string | `"library/busybox"` | Test image repo | +| test.image.tag | string | `"latest"` | Test image tag | +| tolerations | list | `[]` | Tolerations applied to Pods | diff --git a/charts/loki/charts/grafana-agent-operator/README.md.gotmpl b/charts/loki/charts/grafana-agent-operator/README.md.gotmpl new file mode 100644 index 0000000..3dce97a --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/README.md.gotmpl @@ -0,0 +1,52 @@ +{{ template "chart.header" . }} + +{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} + +{{ template "chart.description" . }} + +⚠️ **Please create issues relating to this Helm chart in the [Agent](https://github.com/grafana/agent/issues) repo.** + +{{ template "chart.sourcesSection" . }} + +{{ template "chart.requirementsSection" . }} + +Note that this chart does not provision custom resources like `GrafanaAgent` and `MetricsInstance` (formerly `PrometheusInstance`) or any `*Monitor` resources. + +To learn how to deploy these resources, please see Grafana's [Agent Operator getting started guide](https://grafana.com/docs/agent/latest/operator/getting-started/). + +## CRDs + +The CRDs are synced into this chart manually (for now) from the Grafana Agent [GitHub repo](https://github.com/grafana/agent/tree/main/operations/agent-static-operator/crds). To learn more about how Helm manages CRDs, please see [Custom Resource Definitions](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/) from the Helm docs. + +## Get Repo Info + +```console +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release grafana/grafana-agent-operator +``` + +## Uninstalling the Chart + +To uninstall/delete the my-release deployment: + +```console +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Upgrading an existing Release to a new major version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an incompatible breaking change needing manual actions. Until this chart's version reaches `v1.0`, there are no promises of backwards compatibility. + +{{ template "chart.valuesSection" . }} diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_podmonitors.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_podmonitors.yaml new file mode 100644 index 0000000..153677b --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_podmonitors.yaml @@ -0,0 +1,424 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: podmonitors.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: PodMonitor + listKind: PodMonitorList + plural: podmonitors + shortNames: + - pmon + singular: podmonitor + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + attachMetadata: + properties: + node: + type: boolean + type: object + jobLabel: + type: string + labelLimit: + format: int64 + type: integer + labelNameLengthLimit: + format: int64 + type: integer + labelValueLengthLimit: + format: int64 + type: integer + namespaceSelector: + properties: + any: + type: boolean + matchNames: + items: + type: string + type: array + type: object + podMetricsEndpoints: + items: + properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHttp2: + type: boolean + filterRunning: + type: boolean + followRedirects: + type: boolean + honorLabels: + type: boolean + honorTimestamps: + type: boolean + interval: + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + params: + additionalProperties: + items: + type: string + type: array + type: object + path: + type: string + port: + type: string + proxyUrl: + type: string + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + enum: + - http + - https + type: string + scrapeTimeout: + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + type: boolean + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + type: array + podTargetLabels: + items: + type: string + type: array + sampleLimit: + format: int64 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + targetLimit: + format: int64 + type: integer + required: + - podMetricsEndpoints + - selector + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_probes.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_probes.yaml new file mode 100644 index 0000000..13fc36f --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_probes.yaml @@ -0,0 +1,458 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: probes.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: Probe + listKind: ProbeList + plural: probes + shortNames: + - prb + singular: probe + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + interval: + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + jobName: + type: string + labelLimit: + format: int64 + type: integer + labelNameLengthLimit: + format: int64 + type: integer + labelValueLengthLimit: + format: int64 + type: integer + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + module: + type: string + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + prober: + properties: + path: + default: /probe + type: string + proxyUrl: + type: string + scheme: + enum: + - http + - https + type: string + url: + type: string + required: + - url + type: object + sampleLimit: + format: int64 + type: integer + scrapeTimeout: + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetLimit: + format: int64 + type: integer + targets: + properties: + ingress: + properties: + namespaceSelector: + properties: + any: + type: boolean + matchNames: + items: + type: string + type: array + type: object + relabelingConfigs: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + staticConfig: + properties: + labels: + additionalProperties: + type: string + type: object + relabelingConfigs: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + static: + items: + type: string + type: array + type: object + type: object + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + type: boolean + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_servicemonitors.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_servicemonitors.yaml new file mode 100644 index 0000000..ff62f8f --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_servicemonitors.yaml @@ -0,0 +1,436 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: servicemonitors.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: ServiceMonitor + listKind: ServiceMonitorList + plural: servicemonitors + shortNames: + - smon + singular: servicemonitor + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + attachMetadata: + properties: + node: + type: boolean + type: object + endpoints: + items: + properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenFile: + type: string + bearerTokenSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHttp2: + type: boolean + filterRunning: + type: boolean + followRedirects: + type: boolean + honorLabels: + type: boolean + honorTimestamps: + type: boolean + interval: + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + params: + additionalProperties: + items: + type: string + type: array + type: object + path: + type: string + port: + type: string + proxyUrl: + type: string + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + enum: + - http + - https + type: string + scrapeTimeout: + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + type: array + jobLabel: + type: string + labelLimit: + format: int64 + type: integer + labelNameLengthLimit: + format: int64 + type: integer + labelValueLengthLimit: + format: int64 + type: integer + namespaceSelector: + properties: + any: + type: boolean + matchNames: + items: + type: string + type: array + type: object + podTargetLabels: + items: + type: string + type: array + sampleLimit: + format: int64 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + targetLabels: + items: + type: string + type: array + targetLimit: + format: int64 + type: integer + required: + - endpoints + - selector + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_grafanaagents.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_grafanaagents.yaml new file mode 100644 index 0000000..4ec31d6 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_grafanaagents.yaml @@ -0,0 +1,3711 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: grafanaagents.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: GrafanaAgent + listKind: GrafanaAgentList + plural: grafanaagents + singular: grafanaagent + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + apiServer: + properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + type: string + bearerTokenFile: + type: string + host: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + required: + - host + type: object + configMaps: + items: + type: string + type: array + configReloaderImage: + type: string + configReloaderVersion: + type: string + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + disableReporting: + default: false + type: boolean + disableSupportBundle: + default: false + type: boolean + enableConfigReadAPI: + default: false + type: boolean + image: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + integrations: + properties: + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + logFormat: + type: string + logLevel: + type: string + logs: + properties: + clients: + items: + properties: + backoffConfig: + properties: + maxPeriod: + type: string + maxRetries: + type: integer + minPeriod: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + batchSize: + type: integer + batchWait: + type: string + bearerToken: + type: string + bearerTokenFile: + type: string + externalLabels: + additionalProperties: + type: string + type: object + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyUrl: + type: string + tenantId: + type: string + timeout: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + url: + type: string + required: + - url + type: object + type: array + enforcedNamespaceLabel: + type: string + ignoreNamespaceSelectors: + type: boolean + instanceNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + instanceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + logsExternalLabelName: + type: string + type: object + metrics: + properties: + arbitraryFSAccessThroughSMs: + properties: + deny: + type: boolean + type: object + enforcedNamespaceLabel: + type: string + enforcedSampleLimit: + format: int64 + type: integer + enforcedTargetLimit: + format: int64 + type: integer + externalLabels: + additionalProperties: + type: string + type: object + ignoreNamespaceSelectors: + type: boolean + instanceNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + instanceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + metricsExternalLabelName: + type: string + overrideHonorLabels: + type: boolean + overrideHonorTimestamps: + type: boolean + remoteWrite: + items: + properties: + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + type: string + bearerTokenFile: + type: string + headers: + additionalProperties: + type: string + type: object + metadataConfig: + properties: + send: + type: boolean + sendInterval: + type: string + type: object + name: + type: string + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyUrl: + type: string + queueConfig: + properties: + batchSendDeadline: + type: string + capacity: + type: integer + maxBackoff: + type: string + maxRetries: + type: integer + maxSamplesPerSend: + type: integer + maxShards: + type: integer + minBackoff: + type: string + minShards: + type: integer + retryOnRateLimit: + type: boolean + type: object + remoteTimeout: + type: string + sigv4: + properties: + accessKey: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + profile: + type: string + region: + type: string + roleARN: + type: string + secretKey: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + url: + type: string + writeRelabelConfigs: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + required: + - url + type: object + type: array + replicaExternalLabelName: + type: string + replicas: + format: int32 + type: integer + scrapeInterval: + type: string + scrapeTimeout: + type: string + shards: + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + type: object + paused: + type: boolean + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: object + portName: + type: string + priorityClassName: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + runtimeClassName: + type: string + secrets: + items: + type: string + type: array + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + storage: + properties: + disableMountSubPath: + type: boolean + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + volumeClaimTemplate: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + status: + properties: + accessModes: + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + phase: + type: string + type: object + type: object + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + version: + type: string + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + served: true + storage: true diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_integrations.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_integrations.yaml new file mode 100644 index 0000000..960b2f7 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_integrations.yaml @@ -0,0 +1,810 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: integrations.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: Integration + listKind: IntegrationList + plural: integrations + singular: integration + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + config: + type: object + x-kubernetes-preserve-unknown-fields: true + configMaps: + items: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + name: + type: string + secrets: + items: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + type: + properties: + allNodes: + type: boolean + unique: + type: boolean + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - config + - name + - type + type: object + type: object + served: true + storage: true diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_logsinstances.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_logsinstances.yaml new file mode 100644 index 0000000..517bb30 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_logsinstances.yaml @@ -0,0 +1,299 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: logsinstances.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: LogsInstance + listKind: LogsInstanceList + plural: logsinstances + singular: logsinstance + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + additionalScrapeConfigs: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clients: + items: + properties: + backoffConfig: + properties: + maxPeriod: + type: string + maxRetries: + type: integer + minPeriod: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + batchSize: + type: integer + batchWait: + type: string + bearerToken: + type: string + bearerTokenFile: + type: string + externalLabels: + additionalProperties: + type: string + type: object + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyUrl: + type: string + tenantId: + type: string + timeout: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + url: + type: string + required: + - url + type: object + type: array + podLogsNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + podLogsSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + targetConfig: + properties: + syncPeriod: + type: string + type: object + type: object + type: object + served: true + storage: true diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_metricsinstances.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_metricsinstances.yaml new file mode 100644 index 0000000..610193f --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_metricsinstances.yaml @@ -0,0 +1,495 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: metricsinstances.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: MetricsInstance + listKind: MetricsInstanceList + plural: metricsinstances + singular: metricsinstance + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + additionalScrapeConfigs: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxWALTime: + type: string + minWALTime: + type: string + podMonitorNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + podMonitorSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + probeNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + probeSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + remoteFlushDeadline: + type: string + remoteWrite: + items: + properties: + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + type: string + bearerTokenFile: + type: string + headers: + additionalProperties: + type: string + type: object + metadataConfig: + properties: + send: + type: boolean + sendInterval: + type: string + type: object + name: + type: string + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyUrl: + type: string + queueConfig: + properties: + batchSendDeadline: + type: string + capacity: + type: integer + maxBackoff: + type: string + maxRetries: + type: integer + maxSamplesPerSend: + type: integer + maxShards: + type: integer + minBackoff: + type: string + minShards: + type: integer + retryOnRateLimit: + type: boolean + type: object + remoteTimeout: + type: string + sigv4: + properties: + accessKey: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + profile: + type: string + region: + type: string + roleARN: + type: string + secretKey: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + url: + type: string + writeRelabelConfigs: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + required: + - url + type: object + type: array + serviceMonitorNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + serviceMonitorSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + walTruncateFrequency: + type: string + writeStaleOnShutdown: + type: boolean + type: object + type: object + served: true + storage: true diff --git a/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_podlogs.yaml b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_podlogs.yaml new file mode 100644 index 0000000..f22d051 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_podlogs.yaml @@ -0,0 +1,308 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: podlogs.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: PodLogs + listKind: PodLogsList + plural: podlogs + singular: podlogs + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + jobLabel: + type: string + namespaceSelector: + properties: + any: + type: boolean + matchNames: + items: + type: string + type: array + type: object + pipelineStages: + items: + properties: + cri: + type: object + docker: + type: object + drop: + properties: + dropCounterReason: + type: string + expression: + type: string + longerThan: + type: string + olderThan: + type: string + source: + type: string + value: + type: string + type: object + json: + properties: + expressions: + additionalProperties: + type: string + type: object + source: + type: string + type: object + labelAllow: + items: + type: string + type: array + labelDrop: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + limit: + properties: + burst: + type: integer + drop: + type: boolean + rate: + type: integer + type: object + match: + properties: + action: + type: string + dropCounterReason: + type: string + pipelineName: + type: string + selector: + type: string + stages: + type: string + required: + - selector + type: object + metrics: + additionalProperties: + properties: + action: + type: string + buckets: + items: + type: string + type: array + countEntryBytes: + type: boolean + description: + type: string + matchAll: + type: boolean + maxIdleDuration: + type: string + prefix: + type: string + source: + type: string + type: + type: string + value: + type: string + required: + - action + - type + type: object + type: object + multiline: + properties: + firstLine: + type: string + maxLines: + type: integer + maxWaitTime: + type: string + required: + - firstLine + type: object + output: + properties: + source: + type: string + required: + - source + type: object + pack: + properties: + ingestTimestamp: + type: boolean + labels: + items: + type: string + type: array + required: + - labels + type: object + regex: + properties: + expression: + type: string + source: + type: string + required: + - expression + type: object + replace: + properties: + expression: + type: string + replace: + type: string + source: + type: string + required: + - expression + type: object + template: + properties: + source: + type: string + template: + type: string + required: + - source + - template + type: object + tenant: + properties: + label: + type: string + source: + type: string + value: + type: string + type: object + timestamp: + properties: + actionOnFailure: + type: string + fallbackFormats: + items: + type: string + type: array + format: + type: string + location: + type: string + source: + type: string + required: + - format + - source + type: object + type: object + type: array + podTargetLabels: + items: + type: string + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + required: + - selector + type: object + type: object + served: true + storage: true diff --git a/charts/loki/charts/grafana-agent-operator/templates/_helpers.tpl b/charts/loki/charts/grafana-agent-operator/templates/_helpers.tpl new file mode 100644 index 0000000..e374499 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/templates/_helpers.tpl @@ -0,0 +1,70 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "ga-operator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +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 "ga-operator.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "ga-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "ga-operator.labels" -}} +{{ include "ga-operator.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: operator +helm.sh/chart: {{ include "ga-operator.chart" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels }} +{{- end }} +{{- with .Values.global.commonLabels }} +{{ toYaml . }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "ga-operator.selectorLabels" -}} +app.kubernetes.io/name: {{ include "ga-operator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "ga-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "ga-operator.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + diff --git a/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrole.yaml b/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrole.yaml new file mode 100644 index 0000000..08ad58c --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrole.yaml @@ -0,0 +1,62 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "ga-operator.fullname" . }} + labels: +{{ include "ga-operator.labels" . | indent 4 }} +rules: +- apiGroups: [monitoring.grafana.com] + resources: + - grafanaagents + - metricsinstances + - logsinstances + - podlogs + - integrations + verbs: [get, list, watch] +- apiGroups: [monitoring.grafana.com] + resources: + - grafanaagents/finalizers + - metricsinstances/finalizers + - logsinstances/finalizers + - podlogs/finalizers + - integrations/finalizers + verbs: [get, list, watch, update] +- apiGroups: [monitoring.coreos.com] + resources: + - podmonitors + - probes + - servicemonitors + verbs: [get, list, watch] +- apiGroups: [monitoring.coreos.com] + resources: + - podmonitors/finalizers + - probes/finalizers + - servicemonitors/finalizers + verbs: [get, list, watch, update] +- apiGroups: [""] + resources: + - namespaces + - nodes + verbs: [get, list, watch] +- apiGroups: [""] + resources: + - secrets + - services + - configmaps + - endpoints + verbs: [get, list, watch, create, update, patch, delete] +- apiGroups: ["apps"] + resources: + - statefulsets + - daemonsets + - deployments + verbs: [get, list, watch, create, update, patch, delete] +{{- with .Values.rbac.podSecurityPolicyName }} +- apiGroups: [policy] + resources: + - podsecuritypolicies + verbs: [use] + resourceNames: [ {{ . }} ] +{{- end -}} +{{- end -}} diff --git a/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrolebinding.yaml b/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrolebinding.yaml new file mode 100644 index 0000000..372d310 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrolebinding.yaml @@ -0,0 +1,17 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "ga-operator.fullname" . }} + labels: +{{ include "ga-operator.labels" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "ga-operator.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "ga-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end -}} + diff --git a/charts/loki/charts/grafana-agent-operator/templates/operator-deployment.yaml b/charts/loki/charts/grafana-agent-operator/templates/operator-deployment.yaml new file mode 100644 index 0000000..3367db1 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/templates/operator-deployment.yaml @@ -0,0 +1,79 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "ga-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "ga-operator.labels" . | indent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: 1 + selector: + matchLabels: +{{ include "ga-operator.selectorLabels" . | indent 6 }} + template: + metadata: + labels: +{{ include "ga-operator.selectorLabels" . | indent 8 }} +{{- with .Values.podLabels }} +{{- toYaml . | nindent 8 }} +{{- end }} +{{- with .Values.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + serviceAccountName: {{ template "ga-operator.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ include "ga-operator.name" . }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- if or (and .Values.kubeletService.namespace .Values.kubeletService.serviceName) (.Values.extraArgs) }} + args: + {{- if and .Values.kubeletService.namespace .Values.kubeletService.serviceName }} + - --kubelet-service={{ .Values.kubeletService.namespace }}/{{ .Values.kubeletService.serviceName }} + {{- end }} + {{- if .Values.extraArgs }} + {{- range .Values.extraArgs }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.image.pullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/loki/charts/grafana-agent-operator/templates/operator-serviceaccount.yaml b/charts/loki/charts/grafana-agent-operator/templates/operator-serviceaccount.yaml new file mode 100644 index 0000000..1f9b207 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/templates/operator-serviceaccount.yaml @@ -0,0 +1,10 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "ga-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "ga-operator.labels" . | indent 4 }} +{{- end -}} + diff --git a/charts/loki/charts/grafana-agent-operator/templates/tests/test-grafanaagent.yaml b/charts/loki/charts/grafana-agent-operator/templates/tests/test-grafanaagent.yaml new file mode 100644 index 0000000..4001da4 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/templates/tests/test-grafanaagent.yaml @@ -0,0 +1,118 @@ +apiVersion: monitoring.grafana.com/v1alpha1 +kind: GrafanaAgent +metadata: + name: grafana-agent-test + labels: + app: grafana-agent-test + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +spec: + image: "{{ .Values.image.registry }}/grafana/agent:{{ .Values.image.tag }}" + logLevel: info + serviceAccountName: grafana-agent-test-sa + metrics: + instanceSelector: + matchLabels: + agent: grafana-agent-test + +--- + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: grafana-agent-test-sa + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: grafana-agent-test-cr + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +rules: +- apiGroups: + - "" + resources: + - nodes + - nodes/proxy + - nodes/metrics + - services + - endpoints + - pods + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- nonResourceURLs: + - /metrics + - /metrics/cadvisor + verbs: + - get + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: grafana-agent-test-crb + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: grafana-agent-test-cr +subjects: +- kind: ServiceAccount + name: grafana-agent-test-sa + namespace: {{ .Release.Namespace }} + +--- + +apiVersion: monitoring.grafana.com/v1alpha1 +kind: MetricsInstance +metadata: + name: primary-test + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed + labels: + agent: grafana-agent-test +spec: {} + +--- + +apiVersion: v1 +kind: Pod +metadata: + name: grafana-agent-test-probe + annotations: + "helm.sh/hook": test + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +spec: + containers: + - name: busybox + image: "{{ .Values.test.image.registry }}/{{ .Values.test.image.repository }}:{{ .Values.test.image.tag }}" + command: ['wget'] + args: ['grafana-agent-test-operated:8080/-/healthy'] + # Wait for GrafanaAgent CR + initContainers: + - name: sleep + image: "{{ .Values.test.image.registry }}/{{ .Values.test.image.repository }}:{{ .Values.test.image.tag }}" + command: ['sleep', '60'] + restartPolicy: Never diff --git a/charts/loki/charts/grafana-agent-operator/values.yaml b/charts/loki/charts/grafana-agent-operator/values.yaml new file mode 100644 index 0000000..0fb0fc9 --- /dev/null +++ b/charts/loki/charts/grafana-agent-operator/values.yaml @@ -0,0 +1,84 @@ +global: + # -- Common labels for all object directly managed by this chart. + commonLabels: {} + +# -- Overrides the chart's name +nameOverride: "" + +# -- Overrides the chart's computed fullname +fullnameOverride: "" + +# -- Annotations for the Deployment +annotations: {} + +# -- Annotations for the Deployment Pods +podAnnotations: {} + +# -- Annotations for the Deployment Pods +podLabels: {} + +# -- Pod security context (runAsUser, etc.) +podSecurityContext: {} + +# -- Container security context (allowPrivilegeEscalation, etc.) +containerSecurityContext: {} + +rbac: + # -- Toggle to create ClusterRole and ClusterRoleBinding + create: true + # -- Name of a PodSecurityPolicy to use in the ClusterRole. If unset, no PodSecurityPolicy is used. + podSecurityPolicyName: '' + +serviceAccount: + # -- Toggle to create ServiceAccount + create: true + # -- Service account name + name: + +image: + # -- Image registry + registry: docker.io + # -- Image repo + repository: grafana/agent-operator + # -- Image tag + tag: v0.44.2 + # -- Image pull policy + pullPolicy: IfNotPresent + # -- Image pull secrets + pullSecrets: [] + +test: + image: + # -- Test image registry + registry: docker.io + # -- Test image repo + repository: library/busybox + # -- Test image tag + tag: latest + +# -- hostAliases to add +hostAliases: [] +# - ip: 1.2.3.4 +# hostnames: +# - domain.tld + +# -- If both are set, Agent Operator will create and maintain a service for scraping kubelets +# https://grafana.com/docs/agent/latest/operator/getting-started/#monitor-kubelets +kubeletService: + namespace: default + serviceName: kubelet + +# -- List of additional cli arguments to configure agent-operator (example: `--log.level`) +extraArgs: [] + +# -- Resource limits and requests config +resources: {} + +# -- nodeSelector configuration +nodeSelector: {} + +# -- Tolerations applied to Pods +tolerations: [] + +# -- Pod affinity configuration +affinity: {} diff --git a/charts/loki/charts/minio/.helmignore b/charts/loki/charts/minio/.helmignore new file mode 100644 index 0000000..a9fe727 --- /dev/null +++ b/charts/loki/charts/minio/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +# OWNERS file for Kubernetes +OWNERS \ No newline at end of file diff --git a/charts/loki/charts/minio/Chart.yaml b/charts/loki/charts/minio/Chart.yaml new file mode 100644 index 0000000..827787e --- /dev/null +++ b/charts/loki/charts/minio/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +appVersion: RELEASE.2024-12-18T13-15-44Z +description: High Performance Object Storage +home: https://min.io +icon: https://min.io/resources/img/logo/MINIO_wordmark.png +keywords: +- minio +- storage +- object-storage +- s3 +- cluster +maintainers: +- email: dev@minio.io + name: MinIO, Inc +name: minio +sources: +- https://github.com/minio/minio +version: 5.4.0 diff --git a/charts/loki/charts/minio/README.md b/charts/loki/charts/minio/README.md new file mode 100644 index 0000000..a1d5c99 --- /dev/null +++ b/charts/loki/charts/minio/README.md @@ -0,0 +1,264 @@ +# MinIO Community Helm Chart + +[![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io) [![license](https://img.shields.io/badge/license-AGPL%20V3-blue)](https://github.com/minio/minio/blob/master/LICENSE) + +MinIO is a High Performance Object Storage released under GNU Affero General Public License v3.0. It is API compatible with Amazon S3 cloud storage service. Use MinIO to build high performance infrastructure for machine learning, analytics and application data workloads. + +| IMPORTANT | +| -------------------------- | +| This Helm chart is community built, maintained, and supported. MinIO does not guarantee support for any given bug, feature request, or update referencing this chart.

MinIO publishes a separate [MinIO Kubernetes Operator and Tenant Helm Chart](https://github.com/minio/operator/tree/master/helm) that is officially maintained and supported. MinIO strongly recommends using the MinIO Kubernetes Operator for production deployments. See [Deploy Operator With Helm](https://min.io/docs/minio/kubernetes/upstream/operations/install-deploy-manage/deploy-operator-helm.html?ref=github) for additional documentation. | + +## Introduction + +This chart bootstraps MinIO Cluster on [Kubernetes](http://kubernetes.io) using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Helm cli with Kubernetes cluster configured. +- PV provisioner support in the underlying infrastructure. (We recommend using ) +- Use Kubernetes version v1.19 and later for best experience. + +## Configure MinIO Helm repo + +```bash +helm repo add minio https://charts.min.io/ +``` + +### Installing the Chart + +Install this chart using: + +```bash +helm install --namespace minio --set rootUser=rootuser,rootPassword=rootpass123 --generate-name minio/minio +``` + +The command deploys MinIO on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +### Installing the Chart (toy-setup) + +Minimal toy setup for testing purposes can be deployed using: + +```bash +helm install --set resources.requests.memory=512Mi --set replicas=1 --set persistence.enabled=false --set mode=standalone --set rootUser=rootuser,rootPassword=rootpass123 --generate-name minio/minio +``` + +### Upgrading the Chart + +You can use Helm to update MinIO version in a live release. Assuming your release is named as `my-release`, get the values using the command: + +```bash +helm get values my-release > old_values.yaml +``` + +Then change the field `image.tag` in `old_values.yaml` file with MinIO image tag you want to use. Now update the chart using + +```bash +helm upgrade -f old_values.yaml my-release minio/minio +``` + +Default upgrade strategies are specified in the `values.yaml` file. Update these fields if you'd like to use a different strategy. + +### Configuration + +Refer the [Values file](./values.yaml) for all the possible config fields. + +You can specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```bash +helm install --name my-release --set persistence.size=1Ti minio/minio +``` + +The above command deploys MinIO server with a 1Ti backing persistent volume. + +Alternately, you can provide a YAML file that specifies parameter values while installing the chart. For example, + +```bash +helm install --name my-release -f values.yaml minio/minio +``` + +### Persistence + +This chart provisions a PersistentVolumeClaim and mounts corresponding persistent volume to default location `/export`. You'll need physical storage available in the Kubernetes cluster for this to work. If you'd rather use `emptyDir`, disable PersistentVolumeClaim by: + +```bash +helm install --set persistence.enabled=false minio/minio +``` + +> *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."* + +### Existing PersistentVolumeClaim + +If a Persistent Volume Claim already exists, specify it during installation. + +1. Create the PersistentVolume +2. Create the PersistentVolumeClaim +3. Install the chart + +```bash +helm install --set persistence.existingClaim=PVC_NAME minio/minio +``` + +### NetworkPolicy + +To enable network policy for MinIO, +install [a networking plugin that implements the Kubernetes +NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin), +and set `networkPolicy.enabled` to `true`. + +For Kubernetes v1.5 & v1.6, you must also turn on NetworkPolicy by setting +the DefaultDeny namespace annotation. Note: this will enforce policy for *all* pods in the namespace: + +``` +kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}" +``` + +When using `Cilium` as a CNI in your cluster, please edit the `flavor` field to `cilium`. + +With NetworkPolicy enabled, traffic will be limited to just port 9000. + +For more precise policy, set `networkPolicy.allowExternal=true`. This will +only allow pods with the generated client label to connect to MinIO. +This label will be displayed in the output of a successful install. + +### Existing secret + +Instead of having this chart create the secret for you, you can supply a preexisting secret, much +like an existing PersistentVolumeClaim. + +First, create the secret: + +```bash +kubectl create secret generic my-minio-secret --from-literal=rootUser=foobarbaz --from-literal=rootPassword=foobarbazqux +``` + +Then install the chart, specifying that you want to use an existing secret: + +```bash +helm install --set existingSecret=my-minio-secret minio/minio +``` + +The following fields are expected in the secret: + +| .data.\ in Secret | Corresponding variable | Description | Required | +|:------------------------|:-----------------------|:---------------|:---------| +| `rootUser` | `rootUser` | Root user. | yes | +| `rootPassword` | `rootPassword` | Root password. | yes | + +All corresponding variables will be ignored in values file. + +### Configure TLS + +To enable TLS for MinIO containers, acquire TLS certificates from a CA or create self-signed certificates. While creating / acquiring certificates ensure the corresponding domain names are set as per the standard [DNS naming conventions](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-identity) in a Kubernetes StatefulSet (for a distributed MinIO setup). Then create a secret using + +```bash +kubectl create secret generic tls-ssl-minio --from-file=path/to/private.key --from-file=path/to/public.crt +``` + +Then install the chart, specifying that you want to use the TLS secret: + +```bash +helm install --set tls.enabled=true,tls.certSecret=tls-ssl-minio minio/minio +``` + +### Installing certificates from third party CAs + +MinIO can connect to other servers, including MinIO nodes or other server types such as NATs and Redis. If these servers use certificates that were not registered with a known CA, add trust for these certificates to MinIO Server by bundling these certificates into a Kubernetes secret and providing it to Helm via the `trustedCertsSecret` value. If `.Values.tls.enabled` is `true` and you're installing certificates for third party CAs, remember to include MinIO's own certificate with key `public.crt`, if it also needs to be trusted. + +For instance, given that TLS is enabled and you need to add trust for MinIO's own CA and for the CA of a Keycloak server, a Kubernetes secret can be created from the certificate files using `kubectl`: + +``` +kubectl -n minio create secret generic minio-trusted-certs --from-file=public.crt --from-file=keycloak.crt +``` + +If TLS is not enabled, you would need only the third party CA: + +``` +kubectl -n minio create secret generic minio-trusted-certs --from-file=keycloak.crt +``` + +The name of the generated secret can then be passed to Helm using a values file or the `--set` parameter: + +``` +trustedCertsSecret: "minio-trusted-certs" + +or + +--set trustedCertsSecret=minio-trusted-certs +``` + +### Create buckets after install + +Install the chart, specifying the buckets you want to create after install: + +```bash +helm install --set buckets[0].name=bucket1,buckets[0].policy=none,buckets[0].purge=false minio/minio +``` + +Description of the configuration parameters used above - + +- `buckets[].name` - name of the bucket to create, must be a string with length > 0 +- `buckets[].policy` - can be one of none|download|upload|public +- `buckets[].purge` - purge if bucket exists already + +### Create policies after install + +Install the chart, specifying the policies you want to create after install: + +```bash +helm install --set policies[0].name=mypolicy,policies[0].statements[0].resources[0]='arn:aws:s3:::bucket1',policies[0].statements[0].actions[0]='s3:ListBucket',policies[0].statements[0].actions[1]='s3:GetObject' minio/minio +``` + +Description of the configuration parameters used above - + +- `policies[].name` - name of the policy to create, must be a string with length > 0 +- `policies[].statements[]` - list of statements, includes actions and resources +- `policies[].statements[].resources[]` - list of resources that applies the statement +- `policies[].statements[].actions[]` - list of actions granted + +### Create user after install + +Install the chart, specifying the users you want to create after install: + +```bash +helm install --set users[0].accessKey=accessKey,users[0].secretKey=secretKey,users[0].policy=none,users[1].accessKey=accessKey2,users[1].secretRef=existingSecret,users[1].secretKey=password,users[1].policy=none minio/minio +``` + +Description of the configuration parameters used above - + +- `users[].accessKey` - accessKey of user +- `users[].secretKey` - secretKey of usersecretRef +- `users[].existingSecret` - secret name that contains the secretKey of user +- `users[].existingSecretKey` - data key in existingSecret secret containing the secretKey +- `users[].policy` - name of the policy to assign to user + +### Create service account after install + +Install the chart, specifying the service accounts you want to create after install: + +```bash +helm install --set svcaccts[0].accessKey=accessKey,svcaccts[0].secretKey=secretKey,svcaccts[0].user=parentUser,svcaccts[1].accessKey=accessKey2,svcaccts[1].secretRef=existingSecret,svcaccts[1].secretKey=password,svcaccts[1].user=parentUser2 minio/minio +``` + +Description of the configuration parameters used above - + +- `svcaccts[].accessKey` - accessKey of service account +- `svcaccts[].secretKey` - secretKey of svcacctsecretRef +- `svcaccts[].existingSecret` - secret name that contains the secretKey of service account +- `svcaccts[].existingSecretKey` - data key in existingSecret secret containing the secretKey +- `svcaccts[].user` - name of the parent user to assign to service account + +## Uninstalling the Chart + +Assuming your release is named as `my-release`, delete it using the command: + +```bash +helm delete my-release +``` + +or + +```bash +helm uninstall my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. diff --git a/charts/loki/charts/minio/templates/NOTES.txt b/charts/loki/charts/minio/templates/NOTES.txt new file mode 100644 index 0000000..ba51b4c --- /dev/null +++ b/charts/loki/charts/minio/templates/NOTES.txt @@ -0,0 +1,43 @@ +{{- if eq .Values.service.type "ClusterIP" "NodePort" }} +MinIO can be accessed via port {{ .Values.service.port }} on the following DNS name from within your cluster: +{{ template "minio.fullname" . }}.{{ .Release.Namespace }}.{{ .Values.clusterDomain }} + +To access MinIO from localhost, run the below commands: + + 1. export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + + 2. kubectl port-forward $POD_NAME 9000 --namespace {{ .Release.Namespace }} + +Read more about port forwarding here: http://kubernetes.io/docs/user-guide/kubectl/kubectl_port-forward/ + +You can now access MinIO server on http://localhost:9000. Follow the below steps to connect to MinIO server with mc client: + + 1. Download the MinIO mc client - https://min.io/docs/minio/linux/reference/minio-mc.html#quickstart + + 2. export MC_HOST_{{ template "minio.fullname" . }}-local=http://$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "minio.secretName" . }} -o jsonpath="{.data.rootUser}" | base64 --decode):$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "minio.secretName" . }} -o jsonpath="{.data.rootPassword}" | base64 --decode)@localhost:{{ .Values.service.port }} + + 3. mc ls {{ template "minio.fullname" . }}-local + +{{- end }} +{{- if eq .Values.service.type "LoadBalancer" }} +MinIO can be accessed via port {{ .Values.service.port }} on an external IP address. Get the service external IP address by: +kubectl get svc --namespace {{ .Release.Namespace }} -l app={{ template "minio.fullname" . }} + +Note that the public IP may take a couple of minutes to be available. + +You can now access MinIO server on http://:9000. Follow the below steps to connect to MinIO server with mc client: + + 1. Download the MinIO mc client - https://min.io/docs/minio/linux/reference/minio-mc.html#quickstart + + 2. export MC_HOST_{{ template "minio.fullname" . }}-local=http://$(kubectl get secret {{ template "minio.secretName" . }} --namespace {{ .Release.Namespace }} -o jsonpath="{.data.rootUser}" | base64 --decode):$(kubectl get secret {{ template "minio.secretName" . }} -o jsonpath="{.data.rootPassword}" | base64 --decode)@:{{ .Values.service.port }} + + 3. mc ls {{ template "minio.fullname" . }} + +Alternately, you can use your browser or the MinIO SDK to access the server - https://min.io/docs/minio/linux/reference/minio-server/minio-server.html +{{- end }} + +{{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} +Note: Since NetworkPolicy is enabled, only pods with label +{{ template "minio.fullname" . }}-client=true" +will be able to connect to this minio cluster. +{{- end }} diff --git a/charts/loki/charts/minio/templates/_helper_create_bucket.txt b/charts/loki/charts/minio/templates/_helper_create_bucket.txt new file mode 100644 index 0000000..83b8dcb --- /dev/null +++ b/charts/loki/charts/minio/templates/_helper_create_bucket.txt @@ -0,0 +1,122 @@ +#!/bin/sh +set -e # Have script exit in the event of a failed command. + +{{- if .Values.configPathmc }} +MC_CONFIG_DIR="{{ .Values.configPathmc }}" +MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}" +{{- else }} +MC="/usr/bin/mc --insecure" +{{- end }} + +# connectToMinio +# Use a check-sleep-check loop to wait for MinIO service to be available +connectToMinio() { + SCHEME=$1 + ATTEMPTS=0 + LIMIT=29 # Allow 30 attempts + set -e # fail if we can't read the keys. + ACCESS=$(cat /config/rootUser) + SECRET=$(cat /config/rootPassword) + set +e # The connections to minio are allowed to fail. + echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" + MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" + $MC_COMMAND + STATUS=$? + until [ $STATUS = 0 ]; do + ATTEMPTS=$(expr $ATTEMPTS + 1) + echo \"Failed attempts: $ATTEMPTS\" + if [ $ATTEMPTS -gt $LIMIT ]; then + exit 1 + fi + sleep 2 # 1 second intervals between attempts + $MC_COMMAND + STATUS=$? + done + set -e # reset `e` as active + return 0 +} + +# checkBucketExists ($bucket) +# Check if the bucket exists, by using the exit code of `mc ls` +checkBucketExists() { + BUCKET=$1 + CMD=$(${MC} stat myminio/$BUCKET >/dev/null 2>&1) + return $? +} + +# createBucket ($bucket, $policy, $purge) +# Ensure bucket exists, purging if asked to +createBucket() { + BUCKET=$1 + POLICY=$2 + PURGE=$3 + VERSIONING=$4 + OBJECTLOCKING=$5 + + # Purge the bucket, if set & exists + # Since PURGE is user input, check explicitly for `true` + if [ $PURGE = true ]; then + if checkBucketExists $BUCKET; then + echo "Purging bucket '$BUCKET'." + set +e # don't exit if this fails + ${MC} rm -r --force myminio/$BUCKET + set -e # reset `e` as active + else + echo "Bucket '$BUCKET' does not exist, skipping purge." + fi + fi + + # Create the bucket if it does not exist and set objectlocking if enabled (NOTE: versioning will be not changed if OBJECTLOCKING is set because it enables versioning to the Buckets created) + if ! checkBucketExists $BUCKET; then + if [ ! -z $OBJECTLOCKING ]; then + if [ $OBJECTLOCKING = true ]; then + echo "Creating bucket with OBJECTLOCKING '$BUCKET'" + ${MC} mb --with-lock myminio/$BUCKET + elif [ $OBJECTLOCKING = false ]; then + echo "Creating bucket '$BUCKET'" + ${MC} mb myminio/$BUCKET + fi + elif [ -z $OBJECTLOCKING ]; then + echo "Creating bucket '$BUCKET'" + ${MC} mb myminio/$BUCKET + else + echo "Bucket '$BUCKET' already exists." + fi + fi + + # set versioning for bucket if objectlocking is disabled or not set + if [ $OBJECTLOCKING = false ]; then + if [ ! -z $VERSIONING ]; then + if [ $VERSIONING = true ]; then + echo "Enabling versioning for '$BUCKET'" + ${MC} version enable myminio/$BUCKET + elif [ $VERSIONING = false ]; then + echo "Suspending versioning for '$BUCKET'" + ${MC} version suspend myminio/$BUCKET + fi + fi + else + echo "Bucket '$BUCKET' versioning unchanged." + fi + + # At this point, the bucket should exist, skip checking for existence + # Set policy on the bucket + echo "Setting policy of bucket '$BUCKET' to '$POLICY'." + ${MC} anonymous set $POLICY myminio/$BUCKET +} + +# Try connecting to MinIO instance +{{- if .Values.tls.enabled }} +scheme=https +{{- else }} +scheme=http +{{- end }} +connectToMinio $scheme + +{{ if .Values.buckets }} +{{ $global := . }} +# Create the buckets +{{- range .Values.buckets }} +createBucket {{ tpl .name $global }} {{ .policy | default "none" | quote }} {{ .purge | default false }} {{ .versioning | default false }} {{ .objectlocking | default false }} +{{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/_helper_create_policy.txt b/charts/loki/charts/minio/templates/_helper_create_policy.txt new file mode 100644 index 0000000..aa58495 --- /dev/null +++ b/charts/loki/charts/minio/templates/_helper_create_policy.txt @@ -0,0 +1,75 @@ +#!/bin/sh +set -e ; # Have script exit in the event of a failed command. + +{{- if .Values.configPathmc }} +MC_CONFIG_DIR="{{ .Values.configPathmc }}" +MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}" +{{- else }} +MC="/usr/bin/mc --insecure" +{{- end }} + +# connectToMinio +# Use a check-sleep-check loop to wait for MinIO service to be available +connectToMinio() { + SCHEME=$1 + ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts + set -e ; # fail if we can't read the keys. + ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ; + set +e ; # The connections to minio are allowed to fail. + echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ; + MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ; + $MC_COMMAND ; + STATUS=$? ; + until [ $STATUS = 0 ] + do + ATTEMPTS=`expr $ATTEMPTS + 1` ; + echo \"Failed attempts: $ATTEMPTS\" ; + if [ $ATTEMPTS -gt $LIMIT ]; then + exit 1 ; + fi ; + sleep 2 ; # 1 second intervals between attempts + $MC_COMMAND ; + STATUS=$? ; + done ; + set -e ; # reset `e` as active + return 0 +} + +# checkPolicyExists ($policy) +# Check if the policy exists, by using the exit code of `mc admin policy info` +checkPolicyExists() { + POLICY=$1 + CMD=$(${MC} admin policy info myminio $POLICY > /dev/null 2>&1) + return $? +} + +# createPolicy($name, $filename) +createPolicy () { + NAME=$1 + FILENAME=$2 + + # Create the name if it does not exist + echo "Checking policy: $NAME (in /config/$FILENAME.json)" + if ! checkPolicyExists $NAME ; then + echo "Creating policy '$NAME'" + else + echo "Policy '$NAME' already exists." + fi + ${MC} admin policy create myminio $NAME /config/$FILENAME.json + +} + +# Try connecting to MinIO instance +{{- if .Values.tls.enabled }} +scheme=https +{{- else }} +scheme=http +{{- end }} +connectToMinio $scheme + +{{ if .Values.policies }} +# Create the policies +{{- range $idx, $policy := .Values.policies }} +createPolicy {{ $policy.name }} policy_{{ $idx }} +{{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/_helper_create_svcacct.txt b/charts/loki/charts/minio/templates/_helper_create_svcacct.txt new file mode 100644 index 0000000..5c8aec4 --- /dev/null +++ b/charts/loki/charts/minio/templates/_helper_create_svcacct.txt @@ -0,0 +1,106 @@ +#!/bin/sh +set -e ; # Have script exit in the event of a failed command. + +{{- if .Values.configPathmc }} +MC_CONFIG_DIR="{{ .Values.configPathmc }}" +MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}" +{{- else }} +MC="/usr/bin/mc --insecure" +{{- end }} + +# AccessKey and secretkey credentials file are added to prevent shell execution errors caused by special characters. +# Special characters for example : ',",<,>,{,} +MINIO_ACCESSKEY_SECRETKEY_TMP="/tmp/accessKey_and_secretKey_svcacct_tmp" + +# connectToMinio +# Use a check-sleep-check loop to wait for MinIO service to be available +connectToMinio() { + SCHEME=$1 + ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts + set -e ; # fail if we can't read the keys. + ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ; + set +e ; # The connections to minio are allowed to fail. + echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ; + MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ; + $MC_COMMAND ; + STATUS=$? ; + until [ $STATUS = 0 ] + do + ATTEMPTS=`expr $ATTEMPTS + 1` ; + echo \"Failed attempts: $ATTEMPTS\" ; + if [ $ATTEMPTS -gt $LIMIT ]; then + exit 1 ; + fi ; + sleep 2 ; # 2 second intervals between attempts + $MC_COMMAND ; + STATUS=$? ; + done ; + set -e ; # reset `e` as active + return 0 +} + +# checkSvcacctExists () +# Check if the svcacct exists, by using the exit code of `mc admin user svcacct info` +checkSvcacctExists() { + CMD=$(${MC} admin user svcacct info myminio $(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) > /dev/null 2>&1) + return $? +} + +# createSvcacct ($user) +createSvcacct () { + USER=$1 + FILENAME=$2 + #check accessKey_and_secretKey_tmp file + if [[ ! -f $MINIO_ACCESSKEY_SECRETKEY_TMP ]];then + echo "credentials file does not exist" + return 1 + fi + if [[ $(cat $MINIO_ACCESSKEY_SECRETKEY_TMP|wc -l) -ne 2 ]];then + echo "credentials file is invalid" + rm -f $MINIO_ACCESSKEY_SECRETKEY_TMP + return 1 + fi + SVCACCT=$(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) + # Create the svcacct if it does not exist + if ! checkSvcacctExists ; then + echo "Creating svcacct '$SVCACCT'" + # Check if policy file is define + if [ -z $FILENAME ]; then + ${MC} admin user svcacct add --access-key $(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) --secret-key $(tail -n1 $MINIO_ACCESSKEY_SECRETKEY_TMP) myminio $USER + else + ${MC} admin user svcacct add --access-key $(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) --secret-key $(tail -n1 $MINIO_ACCESSKEY_SECRETKEY_TMP) --policy /config/$FILENAME.json myminio $USER + fi + else + echo "Svcacct '$SVCACCT' already exists." + fi + #clean up credentials files. + rm -f $MINIO_ACCESSKEY_SECRETKEY_TMP +} + +# Try connecting to MinIO instance +{{- if .Values.tls.enabled }} +scheme=https +{{- else }} +scheme=http +{{- end }} +connectToMinio $scheme + +{{ if .Values.svcaccts }} +{{ $global := . }} +# Create the svcaccts +{{- range $idx, $svc := .Values.svcaccts }} +echo {{ tpl .accessKey $global }} > $MINIO_ACCESSKEY_SECRETKEY_TMP +{{- if .existingSecret }} +cat /config/secrets-svc/{{ tpl .existingSecret $global }}/{{ tpl .existingSecretKey $global }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP +# Add a new line if it doesn't exist +echo >> $MINIO_ACCESSKEY_SECRETKEY_TMP +{{ else }} +echo {{ .secretKey }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP +{{- end }} +{{- if $svc.policy}} +createSvcacct {{ .user }} svc_policy_{{ $idx }} +{{ else }} +createSvcacct {{ .user }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/_helper_create_user.txt b/charts/loki/charts/minio/templates/_helper_create_user.txt new file mode 100644 index 0000000..bfb79be --- /dev/null +++ b/charts/loki/charts/minio/templates/_helper_create_user.txt @@ -0,0 +1,107 @@ +#!/bin/sh +set -e ; # Have script exit in the event of a failed command. + +{{- if .Values.configPathmc }} +MC_CONFIG_DIR="{{ .Values.configPathmc }}" +MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}" +{{- else }} +MC="/usr/bin/mc --insecure" +{{- end }} + +# AccessKey and secretkey credentials file are added to prevent shell execution errors caused by special characters. +# Special characters for example : ',",<,>,{,} +MINIO_ACCESSKEY_SECRETKEY_TMP="/tmp/accessKey_and_secretKey_tmp" + +# connectToMinio +# Use a check-sleep-check loop to wait for MinIO service to be available +connectToMinio() { + SCHEME=$1 + ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts + set -e ; # fail if we can't read the keys. + ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ; + set +e ; # The connections to minio are allowed to fail. + echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ; + MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ; + $MC_COMMAND ; + STATUS=$? ; + until [ $STATUS = 0 ] + do + ATTEMPTS=`expr $ATTEMPTS + 1` ; + echo \"Failed attempts: $ATTEMPTS\" ; + if [ $ATTEMPTS -gt $LIMIT ]; then + exit 1 ; + fi ; + sleep 2 ; # 1 second intervals between attempts + $MC_COMMAND ; + STATUS=$? ; + done ; + set -e ; # reset `e` as active + return 0 +} + +# checkUserExists () +# Check if the user exists, by using the exit code of `mc admin user info` +checkUserExists() { + CMD=$(${MC} admin user info myminio $(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) > /dev/null 2>&1) + return $? +} + +# createUser ($policy) +createUser() { + POLICY=$1 + #check accessKey_and_secretKey_tmp file + if [[ ! -f $MINIO_ACCESSKEY_SECRETKEY_TMP ]];then + echo "credentials file does not exist" + return 1 + fi + if [[ $(cat $MINIO_ACCESSKEY_SECRETKEY_TMP|wc -l) -ne 2 ]];then + echo "credentials file is invalid" + rm -f $MINIO_ACCESSKEY_SECRETKEY_TMP + return 1 + fi + USER=$(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) + # Create the user if it does not exist + if ! checkUserExists ; then + echo "Creating user '$USER'" + cat $MINIO_ACCESSKEY_SECRETKEY_TMP | ${MC} admin user add myminio + else + echo "User '$USER' already exists." + fi + #clean up credentials files. + rm -f $MINIO_ACCESSKEY_SECRETKEY_TMP + + # set policy for user + if [ ! -z $POLICY -a $POLICY != " " ] ; then + echo "Adding policy '$POLICY' for '$USER'" + set +e ; # policy already attach errors out, allow it. + ${MC} admin policy attach myminio $POLICY --user=$USER + set -e + else + echo "User '$USER' has no policy attached." + fi +} + +# Try connecting to MinIO instance +{{- if .Values.tls.enabled }} +scheme=https +{{- else }} +scheme=http +{{- end }} +connectToMinio $scheme + +{{ if .Values.users }} +{{ $global := . }} +# Create the users +{{- range .Values.users }} +echo {{ tpl .accessKey $global }} > $MINIO_ACCESSKEY_SECRETKEY_TMP +{{- if .existingSecret }} +cat /config/secrets/{{ tpl .existingSecret $global }}/{{ tpl .existingSecretKey $global }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP +# Add a new line if it doesn't exist +echo >> $MINIO_ACCESSKEY_SECRETKEY_TMP +createUser {{ .policy }} +{{ else }} +echo {{ .secretKey }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP +createUser {{ .policy }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/_helper_custom_command.txt b/charts/loki/charts/minio/templates/_helper_custom_command.txt new file mode 100644 index 0000000..b583a77 --- /dev/null +++ b/charts/loki/charts/minio/templates/_helper_custom_command.txt @@ -0,0 +1,58 @@ +#!/bin/sh +set -e ; # Have script exit in the event of a failed command. + +{{- if .Values.configPathmc }} +MC_CONFIG_DIR="{{ .Values.configPathmc }}" +MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}" +{{- else }} +MC="/usr/bin/mc --insecure" +{{- end }} + +# connectToMinio +# Use a check-sleep-check loop to wait for MinIO service to be available +connectToMinio() { + SCHEME=$1 + ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts + set -e ; # fail if we can't read the keys. + ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ; + set +e ; # The connections to minio are allowed to fail. + echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ; + MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ; + $MC_COMMAND ; + STATUS=$? ; + until [ $STATUS = 0 ] + do + ATTEMPTS=`expr $ATTEMPTS + 1` ; + echo \"Failed attempts: $ATTEMPTS\" ; + if [ $ATTEMPTS -gt $LIMIT ]; then + exit 1 ; + fi ; + sleep 2 ; # 1 second intervals between attempts + $MC_COMMAND ; + STATUS=$? ; + done ; + set -e ; # reset `e` as active + return 0 +} + +# runCommand ($@) +# Run custom mc command +runCommand() { + ${MC} "$@" + return $? +} + +# Try connecting to MinIO instance +{{- if .Values.tls.enabled }} +scheme=https +{{- else }} +scheme=http +{{- end }} +connectToMinio $scheme + +{{ if .Values.customCommands }} +# Run custom commands +{{- range .Values.customCommands }} +runCommand {{ .command }} +{{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/_helper_policy.tpl b/charts/loki/charts/minio/templates/_helper_policy.tpl new file mode 100644 index 0000000..8be998e --- /dev/null +++ b/charts/loki/charts/minio/templates/_helper_policy.tpl @@ -0,0 +1,28 @@ +{{- $statements_length := len .statements -}} +{{- $statements_length := sub $statements_length 1 -}} +{ + "Version": "2012-10-17", + "Statement": [ +{{- range $i, $statement := .statements }} + { + "Effect": "{{ $statement.effect | default "Allow" }}", + "Action": [ +"{{ $statement.actions | join "\",\n\"" }}" + ]{{ if $statement.resources }}, + "Resource": [ +"{{ $statement.resources | join "\",\n\"" }}" + ]{{ end }} +{{- if $statement.conditions }} +{{- $condition_len := len $statement.conditions }} +{{- $condition_len := sub $condition_len 1 }} + , + "Condition": { + {{- range $k,$v := $statement.conditions }} + {{- range $operator,$object := $v }} + "{{ $operator }}": { {{ $object }} }{{- if lt $k $condition_len }},{{- end }} + {{- end }}{{- end }} + }{{- end }} + }{{ if lt $i $statements_length }},{{end }} +{{- end }} + ] +} diff --git a/charts/loki/charts/minio/templates/_helpers.tpl b/charts/loki/charts/minio/templates/_helpers.tpl new file mode 100644 index 0000000..1cb209e --- /dev/null +++ b/charts/loki/charts/minio/templates/_helpers.tpl @@ -0,0 +1,218 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "minio.name" -}} + {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +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 "minio.fullname" -}} + {{- if .Values.fullnameOverride -}} + {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- $name := default .Chart.Name .Values.nameOverride -}} + {{- if contains $name .Release.Name -}} + {{- .Release.Name | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "minio.chart" -}} + {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "minio.networkPolicy.apiVersion" -}} + {{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.Version -}} + {{- print "extensions/v1beta1" -}} + {{- else if semverCompare ">=1.7-0, <1.16-0" .Capabilities.KubeVersion.Version -}} + {{- print "networking.k8s.io/v1beta1" -}} + {{- else if semverCompare "^1.16-0" .Capabilities.KubeVersion.Version -}} + {{- print "networking.k8s.io/v1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for deployment. +*/}} +{{- define "minio.deployment.apiVersion" -}} + {{- if semverCompare "<1.9-0" .Capabilities.KubeVersion.Version -}} + {{- print "apps/v1beta2" -}} + {{- else -}} + {{- print "apps/v1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for statefulset. +*/}} +{{- define "minio.statefulset.apiVersion" -}} + {{- if semverCompare "<1.16-0" .Capabilities.KubeVersion.Version -}} + {{- print "apps/v1beta2" -}} + {{- else -}} + {{- print "apps/v1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "minio.ingress.apiVersion" -}} + {{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} + {{- print "extensions/v1beta1" -}} + {{- else if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion -}} + {{- print "networking.k8s.io/v1beta1" -}} + {{- else -}} + {{- print "networking.k8s.io/v1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for console ingress. +*/}} +{{- define "minio.consoleIngress.apiVersion" -}} + {{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} + {{- print "extensions/v1beta1" -}} + {{- else if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion -}} + {{- print "networking.k8s.io/v1beta1" -}} + {{- else -}} + {{- print "networking.k8s.io/v1" -}} + {{- end -}} +{{- end -}} + +{{/* +Determine secret name. +*/}} +{{- define "minio.secretName" -}} + {{- if .Values.existingSecret -}} + {{- .Values.existingSecret }} + {{- else -}} + {{- include "minio.fullname" . -}} + {{- end -}} +{{- end -}} + +{{/* +Determine name for scc role and rolebinding +*/}} +{{- define "minio.sccRoleName" -}} + {{- printf "%s-%s" "scc" (include "minio.fullname" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Properly format optional additional arguments to MinIO binary +*/}} +{{- define "minio.extraArgs" -}} +{{- range .Values.extraArgs -}} +{{ " " }}{{ . }} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "minio.imagePullSecrets" -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic. +Also, we can not use a single if because lazy evaluation is not an option +*/}} +{{- if .Values.global }} +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.global.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- else if .Values.imagePullSecrets }} +imagePullSecrets: + {{ toYaml .Values.imagePullSecrets }} +{{- end -}} +{{- else if .Values.imagePullSecrets }} +imagePullSecrets: + {{ toYaml .Values.imagePullSecrets }} +{{- end -}} +{{- end -}} + +{{/* +Formats volumeMount for MinIO TLS keys and trusted certs +*/}} +{{- define "minio.tlsKeysVolumeMount" -}} +{{- if .Values.tls.enabled }} +- name: cert-secret-volume + mountPath: {{ .Values.certsPath }} +{{- end }} +{{- if or .Values.tls.enabled (ne .Values.trustedCertsSecret "") }} +{{- $casPath := printf "%s/CAs" .Values.certsPath | clean }} +- name: trusted-cert-secret-volume + mountPath: {{ $casPath }} +{{- end }} +{{- end -}} + +{{/* +Formats volume for MinIO TLS keys and trusted certs +*/}} +{{- define "minio.tlsKeysVolume" -}} +{{- if .Values.tls.enabled }} +- name: cert-secret-volume + secret: + secretName: {{ tpl .Values.tls.certSecret $ }} + items: + - key: {{ .Values.tls.publicCrt }} + path: public.crt + - key: {{ .Values.tls.privateKey }} + path: private.key +{{- end }} +{{- if or .Values.tls.enabled (ne .Values.trustedCertsSecret "") }} +{{- $certSecret := eq .Values.trustedCertsSecret "" | ternary .Values.tls.certSecret .Values.trustedCertsSecret }} +{{- $publicCrt := eq .Values.trustedCertsSecret "" | ternary .Values.tls.publicCrt "" }} +- name: trusted-cert-secret-volume + secret: + secretName: {{ $certSecret }} + {{- if ne $publicCrt "" }} + items: + - key: {{ $publicCrt }} + path: public.crt + {{- end }} +{{- end }} +{{- end -}} + +{{/* +Returns the available value for certain key in an existing secret (if it exists), +otherwise it generates a random value. +*/}} +{{- define "minio.getValueFromSecret" }} + {{- $len := (default 16 .Length) | int -}} + {{- $obj := (lookup "v1" "Secret" .Namespace .Name).data -}} + {{- if $obj }} + {{- index $obj .Key | b64dec -}} + {{- else -}} + {{- randAlphaNum $len -}} + {{- end -}} +{{- end }} + +{{- define "minio.root.username" -}} + {{- if .Values.rootUser }} + {{- .Values.rootUser | toString }} + {{- else }} + {{- include "minio.getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "minio.fullname" .) "Length" 20 "Key" "rootUser") }} + {{- end }} +{{- end -}} + +{{- define "minio.root.password" -}} + {{- if .Values.rootPassword }} + {{- .Values.rootPassword | toString }} + {{- else }} + {{- include "minio.getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "minio.fullname" .) "Length" 40 "Key" "rootPassword") }} + {{- end }} +{{- end -}} diff --git a/charts/loki/charts/minio/templates/ciliumnetworkpolicy.yaml b/charts/loki/charts/minio/templates/ciliumnetworkpolicy.yaml new file mode 100644 index 0000000..1dc91bc --- /dev/null +++ b/charts/loki/charts/minio/templates/ciliumnetworkpolicy.yaml @@ -0,0 +1,33 @@ +{{- if and (.Values.networkPolicy.enabled) (eq .Values.networkPolicy.flavor "cilium") }} +kind: CiliumNetworkPolicy +apiVersion: cilium.io/v2 +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + endpointSelector: + matchLabels: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} + ingress: + - toPorts: + - ports: + - port: "{{ .Values.minioAPIPort }}" + protocol: TCP + - port: "{{ .Values.minioConsolePort }}" + protocol: TCP + {{- if not .Values.networkPolicy.allowExternal }} + fromEndpoints: + - matchLabels: + {{ template "minio.name" . }}-client: "true" + {{- end }} + egress: + {{- range $entity := .Values.networkPolicy.egressEntities }} + - toEntities: + - {{ $entity }} + {{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/configmap.yaml b/charts/loki/charts/minio/templates/configmap.yaml new file mode 100644 index 0000000..47f64cc --- /dev/null +++ b/charts/loki/charts/minio/templates/configmap.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + initialize: |- + {{- include (print $.Template.BasePath "/_helper_create_bucket.txt") . | nindent 4 }} + add-user: |- + {{- include (print $.Template.BasePath "/_helper_create_user.txt") . | nindent 4 }} + add-policy: |- + {{- include (print $.Template.BasePath "/_helper_create_policy.txt") . | nindent 4 }} + {{- range $idx, $policy := .Values.policies }} + # Policy: {{ $policy.name }} + policy_{{ $idx }}.json: |- + {{- include (print $.Template.BasePath "/_helper_policy.tpl") . | nindent 4 }} + {{ end }} + {{- range $idx, $svc := .Values.svcaccts }} + {{- if $svc.policy }} + # SVC: {{ $svc.accessKey }} + svc_policy_{{ $idx }}.json: |- + {{- include (print $.Template.BasePath "/_helper_policy.tpl") .policy | nindent 4 }} + {{- end }} + {{- end }} + add-svcacct: |- + {{- include (print $.Template.BasePath "/_helper_create_svcacct.txt") . | nindent 4 }} + custom-command: |- + {{- include (print $.Template.BasePath "/_helper_custom_command.txt") . | nindent 4 }} diff --git a/charts/loki/charts/minio/templates/console-ingress.yaml b/charts/loki/charts/minio/templates/console-ingress.yaml new file mode 100644 index 0000000..79a2b1b --- /dev/null +++ b/charts/loki/charts/minio/templates/console-ingress.yaml @@ -0,0 +1,55 @@ +{{- if .Values.consoleIngress.enabled -}} +{{- $fullName := printf "%s-console" (include "minio.fullname" .) -}} +{{- $servicePort := .Values.consoleService.port -}} +{{- $ingressPath := .Values.consoleIngress.path -}} +apiVersion: {{ template "minio.consoleIngress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.consoleIngress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.consoleIngress.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.consoleIngress.ingressClassName }} + ingressClassName: {{ .Values.consoleIngress.ingressClassName }} + {{- end }} + {{- if .Values.consoleIngress.tls }} + tls: + {{- range .Values.consoleIngress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.consoleIngress.hosts }} + - http: + paths: + - path: {{ $ingressPath }} + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + pathType: Prefix + backend: + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + backend: + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- if . }} + host: {{ tpl . $ | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/console-service.yaml b/charts/loki/charts/minio/templates/console-service.yaml new file mode 100644 index 0000000..f09e3f3 --- /dev/null +++ b/charts/loki/charts/minio/templates/console-service.yaml @@ -0,0 +1,45 @@ +{{ $scheme := .Values.tls.enabled | ternary "https" "http" }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "minio.fullname" . }}-console + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.consoleService.annotations }} + annotations: {{- toYaml .Values.consoleService.annotations | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.consoleService.type }} + {{- if and (eq .Values.consoleService.type "ClusterIP") .Values.consoleService.clusterIP }} + clusterIP: {{ .Values.consoleService.clusterIP }} + {{- end }} + {{- if or (eq .Values.consoleService.type "LoadBalancer") (eq .Values.consoleService.type "NodePort") }} + externalTrafficPolicy: {{ .Values.consoleService.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.consoleService.type "LoadBalancer") .Values.consoleService.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ .Values.consoleService.loadBalancerSourceRanges }} + {{ end }} + {{- if and (eq .Values.consoleService.type "LoadBalancer") (not (empty .Values.consoleService.loadBalancerIP)) }} + loadBalancerIP: {{ .Values.consoleService.loadBalancerIP }} + {{- end }} + ports: + - name: {{ $scheme }} + port: {{ .Values.consoleService.port }} + protocol: TCP + {{- if (and (eq .Values.consoleService.type "NodePort") ( .Values.consoleService.nodePort)) }} + nodePort: {{ .Values.consoleService.nodePort }} + {{- else }} + targetPort: {{ .Values.minioConsolePort }} + {{- end }} + {{- if .Values.consoleService.externalIPs }} + externalIPs: + {{- range $i , $ip := .Values.consoleService.externalIPs }} + - {{ $ip }} + {{- end }} + {{- end }} + selector: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} diff --git a/charts/loki/charts/minio/templates/deployment.yaml b/charts/loki/charts/minio/templates/deployment.yaml new file mode 100644 index 0000000..4c57010 --- /dev/null +++ b/charts/loki/charts/minio/templates/deployment.yaml @@ -0,0 +1,213 @@ +{{- if eq .Values.mode "standalone" }} +{{ $scheme := .Values.tls.enabled | ternary "https" "http" }} +{{ $bucketRoot := or ($.Values.bucketRoot) ($.Values.mountPath) }} +apiVersion: {{ template "minio.deployment.apiVersion" . }} +kind: Deployment +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.additionalLabels }} + {{- toYaml .Values.additionalLabels | nindent 4 }} + {{- end }} + {{- if .Values.additionalAnnotations }} + annotations: {{- toYaml .Values.additionalAnnotations | nindent 4 }} + {{- end }} +spec: + strategy: + type: {{ .Values.deploymentUpdate.type }} + {{- if eq .Values.deploymentUpdate.type "RollingUpdate" }} + rollingUpdate: + maxSurge: {{ .Values.deploymentUpdate.maxSurge }} + maxUnavailable: {{ .Values.deploymentUpdate.maxUnavailable }} + {{- end }} + replicas: 1 + selector: + matchLabels: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} + template: + metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} + {{- if .Values.podLabels }} + {{- toYaml .Values.podLabels | nindent 8 }} + {{- end }} + annotations: + {{- if not .Values.ignoreChartChecksums }} + checksum/secrets: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }} + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.podAnnotations }} + {{- toYaml .Values.podAnnotations | trimSuffix "\n" | nindent 8 }} + {{- end }} + spec: + {{- if .Values.priorityClassName }} + priorityClassName: "{{ .Values.priorityClassName }}" + {{- end }} + {{- if .Values.runtimeClassName }} + runtimeClassName: "{{ .Values.runtimeClassName }}" + {{- end }} + {{- if and .Values.securityContext.enabled .Values.persistence.enabled }} + securityContext: + {{ omit .Values.securityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{ if .Values.serviceAccount.create }} + serviceAccountName: {{ .Values.serviceAccount.name }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - "/bin/sh" + - "-ce" + - "/usr/bin/docker-entrypoint.sh minio server {{ $bucketRoot }} -S {{ .Values.certsPath }} --address :{{ .Values.minioAPIPort }} --console-address :{{ .Values.minioConsolePort }} {{- template "minio.extraArgs" . }}" + volumeMounts: + - name: minio-user + mountPath: "/tmp/credentials" + readOnly: true + - name: export + mountPath: {{ .Values.mountPath }} + {{- if and .Values.persistence.enabled .Values.persistence.subPath }} + subPath: "{{ .Values.persistence.subPath }}" + {{- end }} + {{- if .Values.extraSecret }} + - name: extra-secret + mountPath: "/tmp/minio-config-env" + {{- end }} + {{- include "minio.tlsKeysVolumeMount" . | indent 12 }} + {{- if .Values.extraVolumeMounts }} + {{- toYaml .Values.extraVolumeMounts | nindent 12 }} + {{- end }} + ports: + - name: {{ $scheme }} + containerPort: {{ .Values.minioAPIPort }} + - name: {{ $scheme }}-console + containerPort: {{ .Values.minioConsolePort }} + env: + - name: MINIO_ROOT_USER + valueFrom: + secretKeyRef: + name: {{ template "minio.secretName" . }} + key: rootUser + - name: MINIO_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "minio.secretName" . }} + key: rootPassword + {{- if .Values.extraSecret }} + - name: MINIO_CONFIG_ENV_FILE + value: "/tmp/minio-config-env/config.env" + {{- end }} + {{- if .Values.metrics.serviceMonitor.public }} + - name: MINIO_PROMETHEUS_AUTH_TYPE + value: "public" + {{- end }} + {{- if .Values.oidc.enabled }} + - name: MINIO_IDENTITY_OPENID_CONFIG_URL + value: {{ .Values.oidc.configUrl }} + - name: MINIO_IDENTITY_OPENID_CLIENT_ID + {{- if and .Values.oidc.existingClientSecretName .Values.oidc.existingClientIdKey }} + valueFrom: + secretKeyRef: + name: {{ .Values.oidc.existingClientSecretName }} + key: {{ .Values.oidc.existingClientIdKey }} + {{- else }} + value: {{ .Values.oidc.clientId }} + {{- end }} + - name: MINIO_IDENTITY_OPENID_CLIENT_SECRET + {{- if and .Values.oidc.existingClientSecretName .Values.oidc.existingClientSecretKey }} + valueFrom: + secretKeyRef: + name: {{ .Values.oidc.existingClientSecretName }} + key: {{ .Values.oidc.existingClientSecretKey }} + {{- else }} + value: {{ .Values.oidc.clientSecret }} + {{- end }} + - name: MINIO_IDENTITY_OPENID_CLAIM_NAME + value: {{ .Values.oidc.claimName }} + - name: MINIO_IDENTITY_OPENID_CLAIM_PREFIX + value: {{ .Values.oidc.claimPrefix }} + - name: MINIO_IDENTITY_OPENID_SCOPES + value: {{ .Values.oidc.scopes }} + - name: MINIO_IDENTITY_OPENID_COMMENT + value: {{ .Values.oidc.comment }} + - name: MINIO_IDENTITY_OPENID_REDIRECT_URI + value: {{ .Values.oidc.redirectUri }} + - name: MINIO_IDENTITY_OPENID_DISPLAY_NAME + value: {{ .Values.oidc.displayName }} + {{- end }} + {{- if .Values.etcd.endpoints }} + - name: MINIO_ETCD_ENDPOINTS + value: {{ join "," .Values.etcd.endpoints | quote }} + {{- if .Values.etcd.clientCert }} + - name: MINIO_ETCD_CLIENT_CERT + value: "/tmp/credentials/etcd_client_cert.pem" + {{- end }} + {{- if .Values.etcd.clientCertKey }} + - name: MINIO_ETCD_CLIENT_CERT_KEY + value: "/tmp/credentials/etcd_client_cert_key.pem" + {{- end }} + {{- if .Values.etcd.pathPrefix }} + - name: MINIO_ETCD_PATH_PREFIX + value: {{ .Values.etcd.pathPrefix }} + {{- end }} + {{- if .Values.etcd.corednsPathPrefix }} + - name: MINIO_ETCD_COREDNS_PATH + value: {{ .Values.etcd.corednsPathPrefix }} + {{- end }} + {{- end }} + {{- range $key, $val := .Values.environment }} + - name: {{ $key }} + value: {{ tpl $val $ | quote }} + {{- end }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- if and .Values.securityContext.enabled .Values.persistence.enabled }} + {{- with .Values.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12}} + {{- end }} + {{- end }} + {{- with .Values.extraContainers }} + {{- if eq (typeOf .) "string" }} + {{- tpl . $ | nindent 8 }} + {{- else }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "minio.imagePullSecrets" . | indent 6 }} + {{- with .Values.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: export + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim | default (include "minio.fullname" .) }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.extraSecret }} + - name: extra-secret + secret: + secretName: {{ .Values.extraSecret }} + {{- end }} + - name: minio-user + secret: + secretName: {{ template "minio.secretName" . }} + {{- include "minio.tlsKeysVolume" . | indent 8 }} + {{- if .Values.extraVolumes }} + {{ toYaml .Values.extraVolumes | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/ingress.yaml b/charts/loki/charts/minio/templates/ingress.yaml new file mode 100644 index 0000000..1a564c6 --- /dev/null +++ b/charts/loki/charts/minio/templates/ingress.yaml @@ -0,0 +1,55 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "minio.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +{{- $ingressPath := .Values.ingress.path -}} +apiVersion: {{ template "minio.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingress.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - http: + paths: + - path: {{ $ingressPath }} + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + pathType: Prefix + backend: + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + backend: + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- if . }} + host: {{ tpl . $ | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/networkpolicy.yaml b/charts/loki/charts/minio/templates/networkpolicy.yaml new file mode 100644 index 0000000..b9c0771 --- /dev/null +++ b/charts/loki/charts/minio/templates/networkpolicy.yaml @@ -0,0 +1,26 @@ +{{- if and (.Values.networkPolicy.enabled) (eq .Values.networkPolicy.flavor "kubernetes") }} +kind: NetworkPolicy +apiVersion: {{ template "minio.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + podSelector: + matchLabels: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} + ingress: + - ports: + - port: {{ .Values.minioAPIPort }} + - port: {{ .Values.minioConsolePort }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ template "minio.name" . }}-client: "true" + {{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/poddisruptionbudget.yaml b/charts/loki/charts/minio/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000..a5f90a0 --- /dev/null +++ b/charts/loki/charts/minio/templates/poddisruptionbudget.yaml @@ -0,0 +1,17 @@ +{{- if .Values.podDisruptionBudget.enabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodDisruptionBudget" }} +apiVersion: policy/v1beta1 +{{- else }} +apiVersion: policy/v1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: minio + labels: + app: {{ template "minio.name" . }} +spec: + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + app: {{ template "minio.name" . }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/post-job.yaml b/charts/loki/charts/minio/templates/post-job.yaml new file mode 100644 index 0000000..955d655 --- /dev/null +++ b/charts/loki/charts/minio/templates/post-job.yaml @@ -0,0 +1,258 @@ +{{- if or .Values.buckets .Values.users .Values.policies .Values.customCommands .Values.svcaccts }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "minio.fullname" . }}-post-job + labels: + app: {{ template "minio.name" . }}-post-job + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation + {{- with .Values.postJob.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + template: + metadata: + labels: + app: {{ template "minio.name" . }}-job + release: {{ .Release.Name }} + {{- if .Values.podLabels }} + {{- toYaml .Values.podLabels | nindent 8 }} + {{- end }} + {{- if .Values.postJob.podAnnotations }} + annotations: {{- toYaml .Values.postJob.podAnnotations | nindent 8 }} + {{- end }} + spec: + restartPolicy: OnFailure + {{- include "minio.imagePullSecrets" . | indent 6 }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.postJob.nodeSelector | nindent 8 }} + {{- end }} + {{- with .Values.postJob.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.postJob.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.postJob.securityContext.enabled }} + securityContext: {{ omit .Values.postJob.securityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + volumes: + - name: etc-path + emptyDir: {} + - name: tmp + emptyDir: {} + - name: minio-configuration + projected: + sources: + - configMap: + name: {{ template "minio.fullname" . }} + - secret: + name: {{ template "minio.secretName" . }} + {{- range (concat .Values.users (default (list) .Values.svcaccts)) }} + {{- if .existingSecret }} + - secret: + name: {{ tpl .existingSecret $ }} + items: + - key: {{ .existingSecretKey }} + path: secrets/{{ tpl .existingSecret $ }}/{{ tpl .existingSecretKey $ }} + {{- end }} + {{- end }} + {{- range ( default list .Values.svcaccts ) }} + {{- if .existingSecret }} + - secret: + name: {{ tpl .existingSecret $ }} + items: + - key: {{ .existingSecretKey }} + path: secrets-svc/{{ tpl .existingSecret $ }}/{{ tpl .existingSecretKey $ }} + {{- end }} + {{- end }} + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + secret: + secretName: {{ .Values.tls.certSecret }} + items: + - key: {{ .Values.tls.publicCrt }} + path: CAs/public.crt + {{- end }} + {{- if .Values.customCommandJob.extraVolumes }} + {{- toYaml .Values.customCommandJob.extraVolumes | nindent 8 }} + {{- end }} + {{- if .Values.serviceAccount.create }} + serviceAccountName: {{ .Values.serviceAccount.name }} + {{- end }} + {{- if .Values.policies }} + initContainers: + - name: minio-make-policy + image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}" + {{- if .Values.makePolicyJob.securityContext.enabled }} + {{- with .Values.makePolicyJob.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.mcImage.pullPolicy }} + {{- if .Values.makePolicyJob.exitCommand }} + command: [ "/bin/sh", "-c" ] + args: [ "/bin/sh /config/add-policy; EV=$?; {{ .Values.makePolicyJob.exitCommand }} && exit $EV" ] + {{- else }} + command: [ "/bin/sh", "/config/add-policy" ] + {{- end }} + env: + - name: MINIO_ENDPOINT + value: {{ template "minio.fullname" . }} + - name: MINIO_PORT + value: {{ .Values.service.port | quote }} + volumeMounts: + - name: etc-path + mountPath: /etc/minio/mc + - name: tmp + mountPath: /tmp + - name: minio-configuration + mountPath: /config + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + mountPath: {{ .Values.configPathmc }}certs + {{- end }} + resources: {{- toYaml .Values.makePolicyJob.resources | nindent 12 }} + {{- end }} + containers: + {{- if .Values.buckets }} + - name: minio-make-bucket + image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}" + {{- if .Values.makeBucketJob.securityContext.enabled }} + {{- with .Values.makeBucketJob.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.mcImage.pullPolicy }} + {{- if .Values.makeBucketJob.exitCommand }} + command: [ "/bin/sh", "-c" ] + args: [ "/bin/sh /config/initialize; EV=$?; {{ .Values.makeBucketJob.exitCommand }} && exit $EV" ] + {{- else }} + command: [ "/bin/sh", "/config/initialize" ] + {{- end }} + env: + - name: MINIO_ENDPOINT + value: {{ template "minio.fullname" . }} + - name: MINIO_PORT + value: {{ .Values.service.port | quote }} + volumeMounts: + - name: etc-path + mountPath: /etc/minio/mc + - name: tmp + mountPath: /tmp + - name: minio-configuration + mountPath: /config + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + mountPath: {{ .Values.configPathmc }}certs + {{- end }} + resources: {{- toYaml .Values.makeBucketJob.resources | nindent 12 }} + {{- end }} + {{- if .Values.users }} + - name: minio-make-user + image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}" + {{- if .Values.makeUserJob.securityContext.enabled }} + {{- with .Values.makeUserJob.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.mcImage.pullPolicy }} + {{- if .Values.makeUserJob.exitCommand }} + command: [ "/bin/sh", "-c" ] + args: [ "/bin/sh /config/add-user; EV=$?; {{ .Values.makeUserJob.exitCommand }} && exit $EV" ] + {{- else }} + command: [ "/bin/sh", "/config/add-user" ] + {{- end }} + env: + - name: MINIO_ENDPOINT + value: {{ template "minio.fullname" . }} + - name: MINIO_PORT + value: {{ .Values.service.port | quote }} + volumeMounts: + - name: etc-path + mountPath: /etc/minio/mc + - name: tmp + mountPath: /tmp + - name: minio-configuration + mountPath: /config + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + mountPath: {{ .Values.configPathmc }}certs + {{- end }} + resources: {{- toYaml .Values.makeUserJob.resources | nindent 12 }} + {{- end }} + {{- if .Values.customCommands }} + - name: minio-custom-command + image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}" + {{- if .Values.customCommandJob.securityContext.enabled }} + {{- with .Values.customCommandJob.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.mcImage.pullPolicy }} + {{- if .Values.customCommandJob.exitCommand }} + command: [ "/bin/sh", "-c" ] + args: [ "/bin/sh /config/custom-command; EV=$?; {{ .Values.customCommandJob.exitCommand }} && exit $EV" ] + {{- else }} + command: [ "/bin/sh", "/config/custom-command" ] + {{- end }} + env: + - name: MINIO_ENDPOINT + value: {{ template "minio.fullname" . }} + - name: MINIO_PORT + value: {{ .Values.service.port | quote }} + volumeMounts: + - name: etc-path + mountPath: /etc/minio/mc + - name: tmp + mountPath: /tmp + - name: minio-configuration + mountPath: /config + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + mountPath: {{ .Values.configPathmc }}certs + {{- end }} + {{- if .Values.customCommandJob.extraVolumeMounts }} + {{- toYaml .Values.customCommandJob.extraVolumeMounts | nindent 12 }} + {{- end }} + resources: {{- toYaml .Values.customCommandJob.resources | nindent 12 }} + {{- end }} + {{- if .Values.svcaccts }} + - name: minio-make-svcacct + image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}" + {{- if .Values.makeServiceAccountJob.securityContext.enabled }} + {{- with .Values.makeServiceAccountJob.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.mcImage.pullPolicy }} + {{- if .Values.makeServiceAccountJob.exitCommand }} + command: [ "/bin/sh", "-c" ] + args: ["/bin/sh /config/add-svcacct; EV=$?; {{ .Values.makeServiceAccountJob.exitCommand }} && exit $EV" ] + {{- else }} + command: ["/bin/sh", "/config/add-svcacct"] + {{- end }} + env: + - name: MINIO_ENDPOINT + value: {{ template "minio.fullname" . }} + - name: MINIO_PORT + value: {{ .Values.service.port | quote }} + volumeMounts: + - name: etc-path + mountPath: /etc/minio/mc + - name: tmp + mountPath: /tmp + - name: minio-configuration + mountPath: /config + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + mountPath: {{ .Values.configPathmc }}certs + {{- end }} + resources: {{- toYaml .Values.makeServiceAccountJob.resources | nindent 12 }} + {{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/pvc.yaml b/charts/loki/charts/minio/templates/pvc.yaml new file mode 100644 index 0000000..60f5267 --- /dev/null +++ b/charts/loki/charts/minio/templates/pvc.yaml @@ -0,0 +1,32 @@ +{{- if eq .Values.mode "standalone" }} +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.persistence.annotations }} + annotations: {{- toYaml .Values.persistence.annotations | nindent 4 }} + {{- end }} +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{- if .Values.persistence.storageClass }} + {{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" + {{- end }} + {{- end }} + {{- if .Values.persistence.volumeName }} + volumeName: "{{ .Values.persistence.volumeName }}" + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/secrets.yaml b/charts/loki/charts/minio/templates/secrets.yaml new file mode 100644 index 0000000..476c3da --- /dev/null +++ b/charts/loki/charts/minio/templates/secrets.yaml @@ -0,0 +1,21 @@ +{{- if not .Values.existingSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "minio.secretName" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +data: + rootUser: {{ include "minio.root.username" . | b64enc | quote }} + rootPassword: {{ include "minio.root.password" . | b64enc | quote }} + {{- if .Values.etcd.clientCert }} + etcd_client.crt: {{ .Values.etcd.clientCert | toString | b64enc | quote }} + {{- end }} + {{- if .Values.etcd.clientCertKey }} + etcd_client.key: {{ .Values.etcd.clientCertKey | toString | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/securitycontextconstraints.yaml b/charts/loki/charts/minio/templates/securitycontextconstraints.yaml new file mode 100644 index 0000000..4bac7e3 --- /dev/null +++ b/charts/loki/charts/minio/templates/securitycontextconstraints.yaml @@ -0,0 +1,45 @@ +{{- if and .Values.securityContext.enabled .Values.persistence.enabled (.Capabilities.APIVersions.Has "security.openshift.io/v1") }} +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +allowHostDirVolumePlugin: false +allowHostIPC: false +allowHostNetwork: false +allowHostPID: false +allowHostPorts: false +allowPrivilegeEscalation: true +allowPrivilegedContainer: false +allowedCapabilities: [] +readOnlyRootFilesystem: false +defaultAddCapabilities: [] +requiredDropCapabilities: +- KILL +- MKNOD +- SETUID +- SETGID +fsGroup: + type: MustRunAs + ranges: + - max: {{ .Values.securityContext.fsGroup }} + min: {{ .Values.securityContext.fsGroup }} +runAsUser: + type: MustRunAs + uid: {{ .Values.securityContext.runAsUser }} +seLinuxContext: + type: MustRunAs +supplementalGroups: + type: RunAsAny +volumes: +- configMap +- downwardAPI +- emptyDir +- persistentVolumeClaim +- projected +- secret +{{- end }} diff --git a/charts/loki/charts/minio/templates/service.yaml b/charts/loki/charts/minio/templates/service.yaml new file mode 100644 index 0000000..d872cd0 --- /dev/null +++ b/charts/loki/charts/minio/templates/service.yaml @@ -0,0 +1,46 @@ +{{ $scheme := .Values.tls.enabled | ternary "https" "http" }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + monitoring: "true" + {{- if .Values.service.annotations }} + annotations: {{- toYaml .Values.service.annotations | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- if and (eq .Values.service.type "ClusterIP") .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + {{- if or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort") }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ .Values.service.loadBalancerSourceRanges }} + {{ end }} + {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP)) }} + loadBalancerIP: {{ default "" .Values.service.loadBalancerIP | quote }} + {{- end }} + ports: + - name: {{ $scheme }} + port: {{ .Values.service.port }} + protocol: TCP + {{- if (and (eq .Values.service.type "NodePort") ( .Values.service.nodePort)) }} + nodePort: {{ .Values.service.nodePort }} + {{- else }} + targetPort: {{ .Values.minioAPIPort }} + {{- end }} + {{- if .Values.service.externalIPs }} + externalIPs: + {{- range $i , $ip := .Values.service.externalIPs }} + - {{ $ip }} + {{- end }} + {{- end }} + selector: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} diff --git a/charts/loki/charts/minio/templates/serviceaccount.yaml b/charts/loki/charts/minio/templates/serviceaccount.yaml new file mode 100644 index 0000000..0784015 --- /dev/null +++ b/charts/loki/charts/minio/templates/serviceaccount.yaml @@ -0,0 +1,6 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.name | quote }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/servicemonitor.yaml b/charts/loki/charts/minio/templates/servicemonitor.yaml new file mode 100644 index 0000000..f875a85 --- /dev/null +++ b/charts/loki/charts/minio/templates/servicemonitor.yaml @@ -0,0 +1,112 @@ +{{- if and .Values.metrics.serviceMonitor.enabled .Values.metrics.serviceMonitor.includeNode }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "minio.fullname" . }} + {{- if .Values.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.metrics.serviceMonitor.namespace }} + {{- end }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.metrics.serviceMonitor.additionalLabels }} + {{- toYaml .Values.metrics.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.annotations }} + annotations: {{- toYaml .Values.metrics.serviceMonitor.annotations | nindent 4 }} + {{- end }} +spec: + endpoints: + {{- if .Values.tls.enabled }} + - port: https + scheme: https + tlsConfig: + ca: + secret: + name: {{ .Values.tls.certSecret }} + key: {{ .Values.tls.publicCrt }} + serverName: {{ template "minio.fullname" . }} + {{- else }} + - port: http + scheme: http + {{- end }} + path: /minio/v2/metrics/node + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelConfigs }} + {{- toYaml .Values.metrics.serviceMonitor.relabelConfigs | nindent 6 }} + {{- end }} + {{- if not .Values.metrics.serviceMonitor.public }} + bearerTokenSecret: + name: {{ template "minio.fullname" . }}-prometheus + key: token + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} + selector: + matchLabels: + app: {{ include "minio.name" . }} + release: {{ .Release.Name }} + monitoring: "true" +{{- end }} +{{- if .Values.metrics.serviceMonitor.enabled }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: Probe +metadata: + name: {{ template "minio.fullname" . }}-cluster + {{- if .Values.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.metrics.serviceMonitor.namespace }} + {{- end }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.metrics.serviceMonitor.additionalLabels }} + {{- toYaml .Values.metrics.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} +spec: + jobName: {{ template "minio.fullname" . }} + {{- if .Values.tls.enabled }} + tlsConfig: + ca: + secret: + name: {{ .Values.tls.certSecret }} + key: {{ .Values.tls.publicCrt }} + serverName: {{ template "minio.fullname" . }} + {{- end }} + prober: + url: {{ template "minio.fullname" . }}.{{ .Release.Namespace }}:{{ .Values.service.port }} + path: /minio/v2/metrics/cluster + {{- if .Values.tls.enabled }} + scheme: https + {{- else }} + scheme: http + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelConfigsCluster }} + {{- toYaml .Values.metrics.serviceMonitor.relabelConfigsCluster | nindent 2 }} + {{- end }} + targets: + staticConfig: + static: + - {{ template "minio.fullname" . }}.{{ .Release.Namespace }} + {{- if not .Values.metrics.serviceMonitor.public }} + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + bearerTokenSecret: + name: {{ template "minio.fullname" . }}-prometheus + key: token + {{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/templates/statefulset.yaml b/charts/loki/charts/minio/templates/statefulset.yaml new file mode 100644 index 0000000..d671eaa --- /dev/null +++ b/charts/loki/charts/minio/templates/statefulset.yaml @@ -0,0 +1,267 @@ +{{- if eq .Values.mode "distributed" }} +{{ $poolCount := .Values.pools | int }} +{{ $nodeCount := .Values.replicas | int }} +{{ $replicas := mul $poolCount $nodeCount }} +{{ $drivesPerNode := .Values.drivesPerNode | int }} +{{ $scheme := .Values.tls.enabled | ternary "https" "http" }} +{{ $mountPath := .Values.mountPath }} +{{ $bucketRoot := or ($.Values.bucketRoot) ($.Values.mountPath) }} +{{ $subPath := .Values.persistence.subPath }} +{{ $penabled := .Values.persistence.enabled }} +{{ $accessMode := .Values.persistence.accessMode }} +{{ $storageClass := .Values.persistence.storageClass }} +{{ $psize := .Values.persistence.size }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "minio.fullname" . }}-svc + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + publishNotReadyAddresses: true + clusterIP: None + ports: + - name: {{ $scheme }} + port: {{ .Values.service.port }} + protocol: TCP + targetPort: {{ .Values.minioAPIPort }} + selector: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} +--- +apiVersion: {{ template "minio.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.additionalLabels }} + {{- toYaml .Values.additionalLabels | nindent 4 }} + {{- end }} + {{- if .Values.additionalAnnotations }} + annotations: {{- toYaml .Values.additionalAnnotations | nindent 4 }} + {{- end }} +spec: + updateStrategy: + type: {{ .Values.statefulSetUpdate.updateStrategy }} + podManagementPolicy: "Parallel" + serviceName: {{ template "minio.fullname" . }}-svc + replicas: {{ $replicas }} + selector: + matchLabels: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} + template: + metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} + {{- if .Values.podLabels }} + {{- toYaml .Values.podLabels | nindent 8 }} + {{- end }} + annotations: + {{- if not .Values.ignoreChartChecksums }} + checksum/secrets: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }} + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.podAnnotations }} + {{- toYaml .Values.podAnnotations | nindent 8 }} + {{- end }} + spec: + {{- if .Values.priorityClassName }} + priorityClassName: "{{ .Values.priorityClassName }}" + {{- end }} + {{- if .Values.runtimeClassName }} + runtimeClassName: "{{ .Values.runtimeClassName }}" + {{- end }} + {{- if and .Values.securityContext.enabled .Values.persistence.enabled }} + securityContext: + {{- omit .Values.securityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{- if .Values.serviceAccount.create }} + serviceAccountName: {{ .Values.serviceAccount.name }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: [ + "/bin/sh", + "-ce", + "/usr/bin/docker-entrypoint.sh minio server {{- range $i := until $poolCount }}{{ $factor := mul $i $nodeCount }}{{ $endIndex := add $factor $nodeCount }}{{ $beginIndex := mul $i $nodeCount }} {{ $scheme }}://{{ template `minio.fullname` $ }}-{{ `{` }}{{ $beginIndex }}...{{ sub $endIndex 1 }}{{ `}`}}.{{ template `minio.fullname` $ }}-svc.{{ $.Release.Namespace }}.svc{{if (gt $drivesPerNode 1)}}{{ $bucketRoot }}-{{ `{` }}0...{{ sub $drivesPerNode 1 }}{{ `}` }}{{ else }}{{ $bucketRoot }}{{end }}{{- end }} -S {{ .Values.certsPath }} --address :{{ .Values.minioAPIPort }} --console-address :{{ .Values.minioConsolePort }} {{- template `minio.extraArgs` . }}" + ] + volumeMounts: + {{- if $penabled }} + {{- if (gt $drivesPerNode 1) }} + {{- range $i := until $drivesPerNode }} + - name: export-{{ $i }} + mountPath: {{ $mountPath }}-{{ $i }} + {{- if and $penabled $subPath }} + subPath: {{ $subPath }} + {{- end }} + {{- end }} + {{- else }} + - name: export + mountPath: {{ $mountPath }} + {{- if and $penabled $subPath }} + subPath: {{ $subPath }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.extraSecret }} + - name: extra-secret + mountPath: "/tmp/minio-config-env" + {{- end }} + {{- include "minio.tlsKeysVolumeMount" . | indent 12 }} + {{- if .Values.extraVolumeMounts }} + {{- toYaml .Values.extraVolumeMounts | nindent 12 }} + {{- end }} + ports: + - name: {{ $scheme }} + containerPort: {{ .Values.minioAPIPort }} + - name: {{ $scheme }}-console + containerPort: {{ .Values.minioConsolePort }} + env: + - name: MINIO_ROOT_USER + valueFrom: + secretKeyRef: + name: {{ template "minio.secretName" . }} + key: rootUser + - name: MINIO_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "minio.secretName" . }} + key: rootPassword + {{- if .Values.extraSecret }} + - name: MINIO_CONFIG_ENV_FILE + value: "/tmp/minio-config-env/config.env" + {{- end }} + {{- if .Values.metrics.serviceMonitor.public }} + - name: MINIO_PROMETHEUS_AUTH_TYPE + value: "public" + {{- end }} + {{- if .Values.oidc.enabled }} + - name: MINIO_IDENTITY_OPENID_CONFIG_URL + value: {{ .Values.oidc.configUrl }} + - name: MINIO_IDENTITY_OPENID_CLIENT_ID + {{- if and .Values.oidc.existingClientSecretName .Values.oidc.existingClientIdKey }} + valueFrom: + secretKeyRef: + name: {{ .Values.oidc.existingClientSecretName }} + key: {{ .Values.oidc.existingClientIdKey }} + {{- else }} + value: {{ .Values.oidc.clientId }} + {{- end }} + - name: MINIO_IDENTITY_OPENID_CLIENT_SECRET + {{- if and .Values.oidc.existingClientSecretName .Values.oidc.existingClientSecretKey }} + valueFrom: + secretKeyRef: + name: {{ .Values.oidc.existingClientSecretName }} + key: {{ .Values.oidc.existingClientSecretKey }} + {{- else }} + value: {{ .Values.oidc.clientSecret }} + {{- end }} + - name: MINIO_IDENTITY_OPENID_CLAIM_NAME + value: {{ .Values.oidc.claimName }} + - name: MINIO_IDENTITY_OPENID_CLAIM_PREFIX + value: {{ .Values.oidc.claimPrefix }} + - name: MINIO_IDENTITY_OPENID_SCOPES + value: {{ .Values.oidc.scopes }} + - name: MINIO_IDENTITY_OPENID_COMMENT + value: {{ .Values.oidc.comment }} + - name: MINIO_IDENTITY_OPENID_REDIRECT_URI + value: {{ .Values.oidc.redirectUri }} + - name: MINIO_IDENTITY_OPENID_DISPLAY_NAME + value: {{ .Values.oidc.displayName }} + {{- end }} + {{- range $key, $val := .Values.environment }} + - name: {{ $key }} + value: {{ tpl $val $ | quote }} + {{- end }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- if and .Values.securityContext.enabled .Values.persistence.enabled }} + {{- with .Values.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12}} + {{- end }} + {{- end }} + {{- with .Values.extraContainers }} + {{- if eq (typeOf .) "string" }} + {{- tpl . $ | nindent 8 }} + {{- else }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "minio.imagePullSecrets" . | indent 6 }} + {{- with .Values.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + {{- if and (gt $replicas 1) (ge .Capabilities.KubeVersion.Major "1") (ge .Capabilities.KubeVersion.Minor "19") }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + volumes: + - name: minio-user + secret: + secretName: {{ template "minio.secretName" . }} + {{- if .Values.extraSecret }} + - name: extra-secret + secret: + secretName: {{ .Values.extraSecret }} + {{- end }} + {{- include "minio.tlsKeysVolume" . | indent 8 }} + {{- if .Values.extraVolumes }} + {{- toYaml .Values.extraVolumes | nindent 8 }} + {{- end }} + {{- if .Values.persistence.enabled }} + volumeClaimTemplates: + {{- if gt $drivesPerNode 1 }} + {{- range $diskId := until $drivesPerNode}} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: export-{{ $diskId }} + {{- if $.Values.persistence.annotations }} + annotations: {{- toYaml $.Values.persistence.annotations | nindent 10 }} + {{- end }} + spec: + accessModes: [ {{ $accessMode | quote }} ] + {{- if $storageClass }} + storageClassName: {{ $storageClass }} + {{- end }} + resources: + requests: + storage: {{ $psize }} + {{- end }} + {{- else }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: export + {{- if $.Values.persistence.annotations }} + annotations: {{- toYaml $.Values.persistence.annotations | nindent 10 }} + {{- end }} + spec: + accessModes: [ {{ $accessMode | quote }} ] + {{- if $storageClass }} + storageClassName: {{ $storageClass }} + {{- end }} + resources: + requests: + storage: {{ $psize }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/charts/minio/values.yaml b/charts/loki/charts/minio/values.yaml new file mode 100644 index 0000000..4c9714e --- /dev/null +++ b/charts/loki/charts/minio/values.yaml @@ -0,0 +1,593 @@ +## Provide a name in place of minio for `app:` labels +## +nameOverride: "" + +## Provide a name to substitute for the full names of resources +## +fullnameOverride: "" + +## set kubernetes cluster domain where minio is running +## +clusterDomain: cluster.local + +## Set default image, imageTag, and imagePullPolicy. mode is used to indicate the +## +image: + repository: quay.io/minio/minio + tag: RELEASE.2024-12-18T13-15-44Z + pullPolicy: IfNotPresent + +imagePullSecrets: [] +# - name: "image-pull-secret" + +## Set default image, imageTag, and imagePullPolicy for the `mc` (the minio +## client used to create a default bucket). +## +mcImage: + repository: quay.io/minio/mc + tag: RELEASE.2024-11-21T17-21-54Z + pullPolicy: IfNotPresent + +## minio mode, i.e. standalone or distributed +mode: distributed ## other supported values are "standalone" + +## Additional labels to include with deployment or statefulset +additionalLabels: {} + +## Additional annotations to include with deployment or statefulset +additionalAnnotations: {} + +## Typically the deployment/statefulset includes checksums of secrets/config, +## So that when these change on a subsequent helm install, the deployment/statefulset +## is restarted. This can result in unnecessary restarts under GitOps tooling such as +## flux, so set to "true" to disable this behaviour. +ignoreChartChecksums: false + +## Additional arguments to pass to minio binary +extraArgs: [] +# example for enabling FTP: +# - --ftp=\"address=:8021\" +# - --ftp=\"passive-port-range=10000-10010\" + +## Additional volumes to minio container +extraVolumes: [] + +## Additional volumeMounts to minio container +extraVolumeMounts: [] + +## Additional sidecar containers +extraContainers: [] + +## Internal port number for MinIO S3 API container +## Change service.port to change external port number +minioAPIPort: "9000" + +## Internal port number for MinIO Browser Console container +## Change consoleService.port to change external port number +minioConsolePort: "9001" + +## Update strategy for Deployments +deploymentUpdate: + type: RollingUpdate + maxUnavailable: 0 + maxSurge: 100% + +## Update strategy for StatefulSets +statefulSetUpdate: + updateStrategy: RollingUpdate + +## Pod priority settings +## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ +## +priorityClassName: "" + +## Pod runtime class name +## ref https://kubernetes.io/docs/concepts/containers/runtime-class/ +## +runtimeClassName: "" + +## Set default rootUser, rootPassword +## rootUser and rootPassword is generated when not set +## Distributed MinIO ref: https://min.io/docs/minio/linux/operations/install-deploy-manage/deploy-minio-multi-node-multi-drive.html +## +rootUser: "" +rootPassword: "" + +## Use existing Secret that store following variables: +## +## | Chart var | .data. in Secret | +## |:----------------------|:-------------------------| +## | rootUser | rootUser | +## | rootPassword | rootPassword | +## +## All mentioned variables will be ignored in values file. +## .data.rootUser and .data.rootPassword are mandatory, +## others depend on enabled status of corresponding sections. +existingSecret: "" + +## Directory on the MinIO pof +certsPath: "/etc/minio/certs/" +configPathmc: "/etc/minio/mc/" + +## Path where PV would be mounted on the MinIO Pod +mountPath: "/export" +## Override the root directory which the minio server should serve from. +## If left empty, it defaults to the value of {{ .Values.mountPath }} +## If defined, it must be a sub-directory of the path specified in {{ .Values.mountPath }} +## +bucketRoot: "" + +# Number of drives attached to a node +drivesPerNode: 1 +# Number of MinIO containers running +replicas: 16 +# Number of expanded MinIO clusters +pools: 1 + +## TLS Settings for MinIO +tls: + enabled: false + ## Create a secret with private.key and public.crt files and pass that here. Ref: https://github.com/minio/minio/tree/master/docs/tls/kubernetes#2-create-kubernetes-secret + certSecret: "" + publicCrt: public.crt + privateKey: private.key + +## Trusted Certificates Settings for MinIO. Ref: https://min.io/docs/minio/linux/operations/network-encryption.html#third-party-certificate-authorities +## Bundle multiple trusted certificates into one secret and pass that here. Ref: https://github.com/minio/minio/tree/master/docs/tls/kubernetes#2-create-kubernetes-secret +## When using self-signed certificates, remember to include MinIO's own certificate in the bundle with key public.crt. +## If certSecret is left empty and tls is enabled, this chart installs the public certificate from .Values.tls.certSecret. +trustedCertsSecret: "" + +## Enable persistence using Persistent Volume Claims +## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ +## +persistence: + enabled: true + annotations: {} + + ## A manually managed Persistent Volume and Claim + ## Requires persistence.enabled: true + ## If defined, PVC must be created manually before volume will be bound + existingClaim: "" + + ## minio data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + ## Storage class of PV to bind. By default it looks for standard storage class. + ## If the PV uses a different storage class, specify that here. + storageClass: "" + volumeName: "" + accessMode: ReadWriteOnce + size: 500Gi + + ## If subPath is set mount a sub folder of a volume instead of the root of the volume. + ## This is especially handy for volume plugins that don't natively support sub mounting (like glusterfs). + ## + subPath: "" + +## Expose the MinIO service to be accessed from outside the cluster (LoadBalancer service). +## or access it from within the cluster (ClusterIP service). Set the service type and the port to serve it. +## ref: http://kubernetes.io/docs/user-guide/services/ +## +service: + type: ClusterIP + clusterIP: ~ + port: "9000" + nodePort: 32000 + loadBalancerIP: ~ + externalIPs: [] + annotations: {} + + ## service.loadBalancerSourceRanges Addresses that are allowed when service is LoadBalancer + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## + #loadBalancerSourceRanges: + # - 10.10.10.0/24 + loadBalancerSourceRanges: [] + + ## service.externalTrafficPolicy minio service external traffic policy + ## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + +## Configure Ingress based on the documentation here: https://kubernetes.io/docs/concepts/services-networking/ingress/ +## + +ingress: + enabled: false + ingressClassName: ~ + labels: {} + # node-role.kubernetes.io/ingress: platform + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + # kubernetes.io/ingress.allow-http: "false" + # kubernetes.io/ingress.global-static-ip-name: "" + # nginx.ingress.kubernetes.io/secure-backends: "true" + # nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + # nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0 + path: / + hosts: + - minio-example.local + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +consoleService: + type: ClusterIP + clusterIP: ~ + port: "9001" + nodePort: 32001 + loadBalancerIP: ~ + externalIPs: [] + annotations: {} + ## consoleService.loadBalancerSourceRanges Addresses that are allowed when service is LoadBalancer + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## + #loadBalancerSourceRanges: + # - 10.10.10.0/24 + loadBalancerSourceRanges: [] + + ## servconsoleServiceice.externalTrafficPolicy minio service external traffic policy + ## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + +consoleIngress: + enabled: false + ingressClassName: ~ + labels: {} + # node-role.kubernetes.io/ingress: platform + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + # kubernetes.io/ingress.allow-http: "false" + # kubernetes.io/ingress.global-static-ip-name: "" + # nginx.ingress.kubernetes.io/secure-backends: "true" + # nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + # nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0 + path: / + hosts: + - console.minio-example.local + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +## Node labels for pod assignment +## Ref: https://kubernetes.io/docs/user-guide/node-selection/ +## +nodeSelector: {} +tolerations: [] +affinity: {} +topologySpreadConstraints: [] + +## Add stateful containers to have security context, if enabled MinIO will run as this +## user and group NOTE: securityContext is only enabled if persistence.enabled=true +securityContext: + enabled: true + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + fsGroupChangePolicy: "OnRootMismatch" + +containerSecurityContext: + readOnlyRootFilesystem: false + +# Additational pod annotations +podAnnotations: {} + +# Additional pod labels +podLabels: {} + +## Configure resource requests and limits +## ref: http://kubernetes.io/docs/user-guide/compute-resources/ +## +resources: + requests: + memory: 16Gi + +## List of policies to be created after minio install +## +## In addition to default policies [readonly|readwrite|writeonly|consoleAdmin|diagnostics] +## you can define additional policies with custom supported actions and resources +policies: [] +## writeexamplepolicy policy grants creation or deletion of buckets with name +## starting with example. In addition, grants objects write permissions on buckets starting with +## example. +# - name: writeexamplepolicy +# statements: +# - effect: Allow # this is the default +# resources: +# - 'arn:aws:s3:::example*/*' +# actions: +# - "s3:AbortMultipartUpload" +# - "s3:GetObject" +# - "s3:DeleteObject" +# - "s3:PutObject" +# - "s3:ListMultipartUploadParts" +# - resources: +# - 'arn:aws:s3:::example*' +# actions: +# - "s3:CreateBucket" +# - "s3:DeleteBucket" +# - "s3:GetBucketLocation" +# - "s3:ListBucket" +# - "s3:ListBucketMultipartUploads" +## readonlyexamplepolicy policy grants access to buckets with name starting with example. +## In addition, grants objects read permissions on buckets starting with example. +# - name: readonlyexamplepolicy +# statements: +# - resources: +# - 'arn:aws:s3:::example*/*' +# actions: +# - "s3:GetObject" +# - resources: +# - 'arn:aws:s3:::example*' +# actions: +# - "s3:GetBucketLocation" +# - "s3:ListBucket" +# - "s3:ListBucketMultipartUploads" +## conditionsexample policy creates all access to example bucket with aws:username="johndoe" and source ip range 10.0.0.0/8 and 192.168.0.0/24 only +# - name: conditionsexample +# statements: +# - resources: +# - 'arn:aws:s3:::example/*' +# actions: +# - 's3:*' +# conditions: +# - StringEquals: '"aws:username": "johndoe"' +# - IpAddress: | +# "aws:SourceIp": [ +# "10.0.0.0/8", +# "192.168.0.0/24" +# ] +# +## Additional Annotations for the Kubernetes Job makePolicyJob +makePolicyJob: + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + memory: 128Mi + # Command to run after the main command on exit + exitCommand: "" + +## List of users to be created after minio install +## +users: + ## Username, password and policy to be assigned to the user + ## Default policies are [readonly|readwrite|writeonly|consoleAdmin|diagnostics] + ## Add new policies as explained here https://min.io/docs/minio/kubernetes/upstream/administration/identity-access-management.html#access-management + ## NOTE: this will fail if LDAP is enabled in your MinIO deployment + ## make sure to disable this if you are using LDAP. + - accessKey: console + secretKey: console123 + policy: consoleAdmin + # Or you can refer to specific secret + #- accessKey: externalSecret + # existingSecret: my-secret + # existingSecretKey: password + # policy: readonly + +## Additional Annotations for the Kubernetes Job makeUserJob +makeUserJob: + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + memory: 128Mi + # Command to run after the main command on exit + exitCommand: "" + +## List of service accounts to be created after minio install +## +svcaccts: [] + ## accessKey, secretKey and parent user to be assigned to the service accounts + ## Add new service accounts as explained here https://min.io/docs/minio/kubernetes/upstream/administration/identity-access-management/minio-user-management.html#service-accounts + # - accessKey: console-svcacct + # secretKey: console123 + # user: console + ## Or you can refer to specific secret + # - accessKey: externalSecret + # existingSecret: my-secret + # existingSecretKey: password + # user: console + ## You also can pass custom policy + # - accessKey: console-svcacct + # secretKey: console123 + # user: console + # policy: + # statements: + # - resources: + # - 'arn:aws:s3:::example*/*' + # actions: + # - "s3:AbortMultipartUpload" + # - "s3:GetObject" + # - "s3:DeleteObject" + # - "s3:PutObject" + # - "s3:ListMultipartUploadParts" + +makeServiceAccountJob: + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + memory: 128Mi + # Command to run after the main command on exit + exitCommand: "" + +## List of buckets to be created after minio install +## +buckets: [] + # # Name of the bucket + # - name: bucket1 + # # Policy to be set on the + # # bucket [none|download|upload|public] + # policy: none + # # Purge if bucket exists already + # purge: false + # # set versioning for + # # bucket [true|false] + # versioning: false # remove this key if you do not want versioning feature + # # set objectlocking for + # # bucket [true|false] NOTE: versioning is enabled by default if you use locking + # objectlocking: false + # - name: bucket2 + # policy: none + # purge: false + # versioning: true + # # set objectlocking for + # # bucket [true|false] NOTE: versioning is enabled by default if you use locking + # objectlocking: false + +## Additional Annotations for the Kubernetes Job makeBucketJob +makeBucketJob: + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + memory: 128Mi + # Command to run after the main command on exit + exitCommand: "" + +## List of command to run after minio install +## NOTE: the mc command TARGET is always "myminio" +customCommands: + # - command: "admin policy attach myminio consoleAdmin --group='cn=ops,cn=groups,dc=example,dc=com'" + +## Additional Annotations for the Kubernetes Job customCommandJob +customCommandJob: + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + memory: 128Mi + ## Additional volumes to add to the post-job. + extraVolumes: [] + # - name: extra-policies + # configMap: + # name: my-extra-policies-cm + ## Additional volumeMounts to add to the custom commands container when + ## running the post-job. + extraVolumeMounts: [] + # - name: extra-policies + # mountPath: /mnt/extras/ + # Command to run after the main command on exit + exitCommand: "" + +## Merge jobs +postJob: + podAnnotations: {} + annotations: {} + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + nodeSelector: {} + tolerations: [] + affinity: {} + +## Use this field to add environment variables relevant to MinIO server. These fields will be passed on to MinIO container(s) +## when Chart is deployed +environment: + ## Please refer for comprehensive list https://min.io/docs/minio/linux/reference/minio-server/minio-server.html + ## MINIO_SUBNET_LICENSE: "License key obtained from https://subnet.min.io" + ## MINIO_BROWSER: "off" + +## The name of a secret in the same kubernetes namespace which contain secret values +## This can be useful for LDAP password, etc +## The key in the secret must be 'config.env' +## +extraSecret: ~ + +## OpenID Identity Management +## The following section documents environment variables for enabling external identity management using an OpenID Connect (OIDC)-compatible provider. +## See https://min.io/docs/minio/linux/operations/external-iam/configure-openid-external-identity-management.html for a tutorial on using these variables. +oidc: + enabled: false + configUrl: "https://identity-provider-url/.well-known/openid-configuration" + clientId: "minio" + clientSecret: "" + # Provide existing client secret from the Kubernetes Secret resource, existing secret will have priority over `clientId` and/or `clientSecret`` + existingClientSecretName: "" + existingClientIdKey: "" + existingClientSecretKey: "" + claimName: "policy" + scopes: "openid,profile,email" + redirectUri: "https://console-endpoint-url/oauth_callback" + # Can leave empty + claimPrefix: "" + comment: "" + displayName: "" + +networkPolicy: + enabled: false + # Specifies whether the policies created will be standard Network Policies (flavor: kubernetes) + # or Cilium Network Policies (flavor: cilium) + flavor: kubernetes + allowExternal: true + # only when using flavor: cilium + egressEntities: + - kube-apiserver + +## PodDisruptionBudget settings +## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ +## +podDisruptionBudget: + enabled: false + maxUnavailable: 1 + +## Specify the service account to use for the MinIO pods. If 'create' is set to 'false' +## and 'name' is left unspecified, the account 'default' will be used. +serviceAccount: + create: true + ## The name of the service account to use. If 'create' is 'true', a service account with that name + ## will be created. + name: "minio-sa" + +metrics: + serviceMonitor: + enabled: false + # scrape each node/pod individually for additional metrics + includeNode: false + public: true + additionalLabels: {} + annotations: {} + # for node metrics + relabelConfigs: {} + # for cluster metrics + relabelConfigsCluster: {} + # metricRelabelings: + # - regex: (server|pod) + # action: labeldrop + namespace: ~ + # Scrape interval, for example `interval: 30s` + interval: ~ + # Scrape timeout, for example `scrapeTimeout: 10s` + scrapeTimeout: ~ + +## ETCD settings: https://github.com/minio/minio/blob/master/docs/sts/etcd.md +## Define endpoints to enable this section. +etcd: + endpoints: [] + pathPrefix: "" + corednsPathPrefix: "" + clientCert: "" + clientCertKey: "" diff --git a/charts/loki/charts/rollout-operator/.helmignore b/charts/loki/charts/rollout-operator/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/loki/charts/rollout-operator/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/loki/charts/rollout-operator/Chart.yaml b/charts/loki/charts/rollout-operator/Chart.yaml new file mode 100644 index 0000000..efd581c --- /dev/null +++ b/charts/loki/charts/rollout-operator/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v2 +appVersion: v0.24.0 +description: Grafana rollout-operator +home: https://github.com/grafana/rollout-operator +kubeVersion: ^1.10.0-0 +name: rollout-operator +type: application +version: 0.24.0 diff --git a/charts/loki/charts/rollout-operator/README.md b/charts/loki/charts/rollout-operator/README.md new file mode 100644 index 0000000..9e676ea --- /dev/null +++ b/charts/loki/charts/rollout-operator/README.md @@ -0,0 +1,72 @@ +# Grafana rollout-operator Helm Chart + +Helm chart for deploying [Grafana rollout-operator](https://github.com/grafana/rollout-operator) to Kubernetes. + +# rollout-operator + +![Version: 0.24.0](https://img.shields.io/badge/Version-0.24.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.24.0](https://img.shields.io/badge/AppVersion-v0.24.0-informational?style=flat-square) + +Grafana rollout-operator + +## Requirements + +Kubernetes: `^1.10.0-0` + +## Installation + +This section describes various use cases for installation, upgrade and migration from different systems and versions. + +### Preparation + +These are the common tasks to perform before any of the use cases. + +```bash +# Add the repository +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +### Installation of Grafana Rollout Operator + +```bash +helm install -n grafana/rollout-operator +``` + +The Grafana rollout-operator should be installed in the same namespace as the statefulsets it is operating upon. +It is not a highly available application and runs as a single pod. + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | | +| fullnameOverride | string | `""` | | +| global.commonLabels | object | `{}` | Common labels for all object directly managed by this chart. | +| hostAliases | list | `[]` | hostAliases to add | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.repository | string | `"grafana/rollout-operator"` | | +| image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | +| imagePullSecrets | list | `[]` | | +| minReadySeconds | int | `10` | | +| nameOverride | string | `""` | | +| nodeSelector | object | `{}` | | +| podAnnotations | object | `{}` | Pod Annotations | +| podLabels | object | `{}` | Pod (extra) Labels | +| podSecurityContext | object | `{}` | | +| priorityClassName | string | `""` | | +| resources.limits.memory | string | `"200Mi"` | | +| resources.requests.cpu | string | `"100m"` | | +| resources.requests.memory | string | `"100Mi"` | | +| securityContext | object | `{}` | | +| serviceAccount.annotations | object | `{}` | Annotations to add to the service account | +| serviceAccount.create | bool | `true` | Specifies whether a service account should be created | +| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | +| serviceMonitor.annotations | object | `{}` | ServiceMonitor annotations | +| serviceMonitor.enabled | bool | `false` | Create ServiceMonitor to scrape metrics for Prometheus | +| serviceMonitor.interval | string | `nil` | ServiceMonitor scrape interval | +| serviceMonitor.labels | object | `{}` | Additional ServiceMonitor labels | +| serviceMonitor.namespace | string | `nil` | Alternative namespace for ServiceMonitor resources | +| serviceMonitor.namespaceSelector | object | `{}` | Namespace selector for ServiceMonitor resources | +| serviceMonitor.relabelings | list | `[]` | ServiceMonitor relabel configs to apply to samples before scraping https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig | +| serviceMonitor.scrapeTimeout | string | `nil` | ServiceMonitor scrape timeout in Go duration format (e.g. 15s) | +| tolerations | list | `[]` | | diff --git a/charts/loki/charts/rollout-operator/README.md.gotmpl b/charts/loki/charts/rollout-operator/README.md.gotmpl new file mode 100644 index 0000000..0ac2d47 --- /dev/null +++ b/charts/loki/charts/rollout-operator/README.md.gotmpl @@ -0,0 +1,38 @@ +# Grafana rollout-operator Helm Chart + +Helm chart for deploying [Grafana rollout-operator]({{ template "chart.homepage" . }}) to Kubernetes. + +{{ template "chart.header" . }} + +{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} + +{{ template "chart.description" . }} + +{{ template "chart.sourcesSection" . }} + +{{ template "chart.requirementsSection" . }} + +## Installation + +This section describes various use cases for installation, upgrade and migration from different systems and versions. + +### Preparation + +These are the common tasks to perform before any of the use cases. + +```bash +# Add the repository +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +### Installation of Grafana Rollout Operator + +```bash +helm install -n grafana/rollout-operator +``` + +The Grafana rollout-operator should be installed in the same namespace as the statefulsets it is operating upon. +It is not a highly available application and runs as a single pod. + +{{ template "chart.valuesSection" . }} diff --git a/charts/loki/charts/rollout-operator/templates/NOTES.txt b/charts/loki/charts/rollout-operator/templates/NOTES.txt new file mode 100644 index 0000000..a76e5ba --- /dev/null +++ b/charts/loki/charts/rollout-operator/templates/NOTES.txt @@ -0,0 +1,10 @@ +Repo : {{ .Chart.Home }} + +Validation: + +Check the logs of the pod and ensure messages for reconcilliation of the statefulsets are present. +``` +kubectl logs -n {{ .Release.Namespace }} -l {{ include "cli.labels" . }} +``` +Example log line: +level=debug ts=2022-04-20T13:59:52.783051541Z msg="reconciling StatefulSet" statefulset=mimir-store-gateway-zone-a diff --git a/charts/loki/charts/rollout-operator/templates/_helpers.tpl b/charts/loki/charts/rollout-operator/templates/_helpers.tpl new file mode 100644 index 0000000..68ae702 --- /dev/null +++ b/charts/loki/charts/rollout-operator/templates/_helpers.tpl @@ -0,0 +1,82 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "rollout-operator.name" -}} +{{- default (include "rollout-operator.chartName" .) .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +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 "rollout-operator.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default (include "rollout-operator.chartName" .) .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Recalculate the chart name, because it may be sub-chart included as rollout_operator, +and _ is not valid in resource names. +*/}} +{{- define "rollout-operator.chartName" -}} +{{- print .Chart.Name | replace "_" "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "rollout-operator.chart" -}} +{{- printf "%s-%s" (include "rollout-operator.chartName" .) .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "rollout-operator.labels" -}} +helm.sh/chart: {{ include "rollout-operator.chart" . }} +{{ include "rollout-operator.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- with .Values.global.commonLabels }} +{{ toYaml . }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "rollout-operator.selectorLabels" -}} +app.kubernetes.io/name: {{ include "rollout-operator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "rollout-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "rollout-operator.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + + +{{- define "cli.labels" -}} +{{- $list := list -}} +{{- range $k, $v := ( include "rollout-operator.selectorLabels" . | fromYaml ) -}} +{{- $list = append $list (printf "%s=%s" $k $v) -}} +{{- end -}} +{{ join "," $list }} +{{- end -}} diff --git a/charts/loki/charts/rollout-operator/templates/deployment.yaml b/charts/loki/charts/rollout-operator/templates/deployment.yaml new file mode 100644 index 0000000..d35b866 --- /dev/null +++ b/charts/loki/charts/rollout-operator/templates/deployment.yaml @@ -0,0 +1,74 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "rollout-operator.fullname" . }} + labels: + {{- include "rollout-operator.labels" . | nindent 4 }} +spec: + replicas: 1 + minReadySeconds: {{ .Values.minReadySeconds }} + selector: + matchLabels: + {{- include "rollout-operator.selectorLabels" . | nindent 6 }} + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "rollout-operator.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "rollout-operator.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: rollout-operator + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - -kubernetes.namespace={{ .Release.Namespace }} + ports: + - name: http-metrics + containerPort: 8001 + protocol: TCP + readinessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 5 + timeoutSeconds: 1 + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/loki/charts/rollout-operator/templates/role.yaml b/charts/loki/charts/rollout-operator/templates/role.yaml new file mode 100644 index 0000000..7bc2570 --- /dev/null +++ b/charts/loki/charts/rollout-operator/templates/role.yaml @@ -0,0 +1,30 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "rollout-operator.fullname" . }} + labels: + {{- include "rollout-operator.labels" . | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - list + - get + - watch + - delete +- apiGroups: + - apps + resources: + - statefulsets + verbs: + - list + - get + - watch +- apiGroups: + - apps + resources: + - statefulsets/status + verbs: + - update diff --git a/charts/loki/charts/rollout-operator/templates/rolebinding.yaml b/charts/loki/charts/rollout-operator/templates/rolebinding.yaml new file mode 100644 index 0000000..d1cfe68 --- /dev/null +++ b/charts/loki/charts/rollout-operator/templates/rolebinding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "rollout-operator.fullname" . }} + labels: + {{- include "rollout-operator.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "rollout-operator.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ include "rollout-operator.serviceAccountName" . }} diff --git a/charts/loki/charts/rollout-operator/templates/service.yaml b/charts/loki/charts/rollout-operator/templates/service.yaml new file mode 100644 index 0000000..60ce5b1 --- /dev/null +++ b/charts/loki/charts/rollout-operator/templates/service.yaml @@ -0,0 +1,18 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "rollout-operator.fullname" . }} + labels: + {{- include "rollout-operator.labels" . | nindent 4 }} +spec: + type: ClusterIP + clusterIP: None + ports: + - port: 8001 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + {{- include "rollout-operator.selectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/charts/rollout-operator/templates/serviceaccount.yaml b/charts/loki/charts/rollout-operator/templates/serviceaccount.yaml new file mode 100644 index 0000000..37698a4 --- /dev/null +++ b/charts/loki/charts/rollout-operator/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "rollout-operator.serviceAccountName" . }} + labels: + {{- include "rollout-operator.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/loki/charts/rollout-operator/templates/servicemonitor.yaml b/charts/loki/charts/rollout-operator/templates/servicemonitor.yaml new file mode 100644 index 0000000..8fa7c1b --- /dev/null +++ b/charts/loki/charts/rollout-operator/templates/servicemonitor.yaml @@ -0,0 +1,36 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "rollout-operator.fullname" . }} + {{- with .Values.serviceMonitor.namespace }} + namespace: {{ . }} + {{- end }} + labels: + {{- include "rollout-operator.labels" . | nindent 4 }} + {{- with .Values.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.serviceMonitor.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- include "rollout-operator.selectorLabels" . | nindent 6 }} + endpoints: + - port: http-metrics + {{- with .Values.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + scheme: http +{{- end -}} diff --git a/charts/loki/charts/rollout-operator/values.yaml b/charts/loki/charts/rollout-operator/values.yaml new file mode 100644 index 0000000..1711671 --- /dev/null +++ b/charts/loki/charts/rollout-operator/values.yaml @@ -0,0 +1,89 @@ +# Default values for rollout-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + + +global: + # -- Common labels for all object directly managed by this chart. + commonLabels: {} + + +image: + repository: grafana/rollout-operator + pullPolicy: IfNotPresent + # -- Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] + +# -- hostAliases to add +hostAliases: [] +# - ip: 1.2.3.4 +# hostnames: +# - domain.tld + +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # -- Specifies whether a service account should be created + create: true + # -- Annotations to add to the service account + annotations: {} + # -- The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +# -- Pod Annotations +podAnnotations: {} + +# -- Pod (extra) Labels +podLabels: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +resources: + limits: + # cpu: "1" + memory: 200Mi + requests: + cpu: 100m + memory: 100Mi + +minReadySeconds: 10 + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +priorityClassName: "" + +serviceMonitor: + # -- Create ServiceMonitor to scrape metrics for Prometheus + enabled: false + # -- Alternative namespace for ServiceMonitor resources + namespace: null + # -- Namespace selector for ServiceMonitor resources + namespaceSelector: {} + # -- ServiceMonitor annotations + annotations: {} + # -- Additional ServiceMonitor labels + labels: {} + # -- ServiceMonitor scrape interval + interval: null + # -- ServiceMonitor scrape timeout in Go duration format (e.g. 15s) + scrapeTimeout: null + # -- ServiceMonitor relabel configs to apply to samples before scraping + # https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + relabelings: [] diff --git a/charts/loki/distributed-values.yaml b/charts/loki/distributed-values.yaml new file mode 100644 index 0000000..78a1f11 --- /dev/null +++ b/charts/loki/distributed-values.yaml @@ -0,0 +1,71 @@ +--- +loki: + schemaConfig: + configs: + - from: 2024-04-01 + store: tsdb + object_store: s3 + schema: v13 + index: + prefix: loki_index_ + period: 24h + ingester: + chunk_encoding: snappy + tracing: + enabled: true + querier: + # Default is 4, if you have enough memory and CPU you can increase, reduce if OOMing + max_concurrent: 4 + +#gateway: +# ingress: +# enabled: true +# hosts: +# - host: FIXME +# paths: +# - path: / +# pathType: Prefix + +deploymentMode: Distributed + +ingester: + replicas: 3 +querier: + replicas: 3 + maxUnavailable: 2 +queryFrontend: + replicas: 2 + maxUnavailable: 1 +queryScheduler: + replicas: 2 +distributor: + replicas: 3 + maxUnavailable: 2 +compactor: + replicas: 1 +indexGateway: + replicas: 2 + maxUnavailable: 1 + +# optional experimental components +bloomPlanner: + replicas: 0 +bloomBuilder: + replicas: 0 +bloomGateway: + replicas: 0 + +# Enable minio for storage +minio: + enabled: true + +# Zero out replica counts of other deployment modes +backend: + replicas: 0 +read: + replicas: 0 +write: + replicas: 0 + +singleBinary: + replicas: 0 diff --git a/charts/loki/docs/examples/README.md b/charts/loki/docs/examples/README.md new file mode 100644 index 0000000..84cbae3 --- /dev/null +++ b/charts/loki/docs/examples/README.md @@ -0,0 +1,4 @@ +## Introduction +The Helm Charts found under the examples directory are getting started examples which you can use to deploy Loki using the Simple Scalable architecture quickly. Currently, the examples include: +- [Deploying Grafana Enterprise Logs (Loki in Enterprise mode)](https://github.com/grafana/loki/tree/main/production/helm/loki/docs/examples/enterprise) +- [Deploying Loki OSS](https://github.com/grafana/loki/tree/main/production/helm/loki/docs/examples/oss) diff --git a/charts/loki/docs/examples/enterprise/README.md b/charts/loki/docs/examples/enterprise/README.md new file mode 100644 index 0000000..82c0d28 --- /dev/null +++ b/charts/loki/docs/examples/enterprise/README.md @@ -0,0 +1,28 @@ +## Introduction +This example gives you an example or getting started overrides value file for deploying Loki (Enterprise Licensed) using the Simple Scalable architecture in GKE and using GCS. + +## Installation of Helm Chart +These instructions assume you already have access to a Kubernetes cluster, GCS Bucket and GCP Service Account which has read/write permissions to that GCS Bucket. + +### Populate Secret Values +Populate the [enterprise-secrets.yaml](./enterprise-secrets.yaml) so that: +- The `gcp_service_account.json` secret has the contents of your GCP Service Account JSON key. +- The `license.jwt` secret has the contents of your Grafana Enterprise Logs license key given to your by Grafana Labs. + +Deploy the secrets file to your k8s cluster with the command: + +`kubectl apply -f enterprise-secrets.yaml` + +### Configure the Helm Chart +Open [overrides-enterprise-gcs.yaml](./overrides-enterprise-gcs.yaml) and replace `{YOUR_GCS_BUCKET}` with the name of your GCS bucket. If there are other things you'd like to configure, view the core [Values.yaml file](https://github.com/grafana/loki/blob/main/production/helm/loki/values.yaml) and override anything else you need to within the overrides-enterprise-gcs.yaml file. + +### Install the Helm chart + +`helm upgrade --install --values {PATH_TO_YOUR_OVERRIDES_YAML_FILE} {YOUR_RELEASE_NAME} grafana/loki-simple-scalable --namespace {KUBERNETES_NAMESPACE}` + +### Get the Token for Grafana to connect +`export POD_NAME=$(kubectl get pods --namespace {KUBERNETES_NAMESPACE} -l "job-name=enterprise-logs-tokengen" -o jsonpath="{.items[0].metadata.name}")` + +`kubectl --namespace {KUBERNETES_NAMESPACE} logs $POD_NAME loki | grep Token` + +Take note of this token, you will need it when connecting Grafana Enterprise Logs to Grafana. diff --git a/charts/loki/docs/examples/enterprise/enterprise-secrets.yaml b/charts/loki/docs/examples/enterprise/enterprise-secrets.yaml new file mode 100644 index 0000000..698e94b --- /dev/null +++ b/charts/loki/docs/examples/enterprise/enterprise-secrets.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Secret +metadata: + name: gel-secrets +type: Opaque +stringData: + gcp_service_account.json: | + { + GCP_SERVICE_ACCOUNT_JSON_HERE + } + + license.jwt: LICENSE_HERE diff --git a/charts/loki/docs/examples/enterprise/overrides-enterprise-gcs.yaml b/charts/loki/docs/examples/enterprise/overrides-enterprise-gcs.yaml new file mode 100644 index 0000000..01210d3 --- /dev/null +++ b/charts/loki/docs/examples/enterprise/overrides-enterprise-gcs.yaml @@ -0,0 +1,83 @@ +enterprise: + enabled: true + useExternalLicense: true + externalLicenseName: gel-secrets + tokengen: + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/gel_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: gel-secrets + mountPath: "/etc/gel_secrets" + extraVolumes: + - name: gel-secrets + secret: + secretName: gel-secrets + items: + - key: license.jwt + path: license.jwt + - key: gcp_service_account.json + path: gcp_service_account.json +loki: + auth_enabled: true + + storage: + type: gcs + bucketNames: + chunks: {YOUR_GCS_BUCKET} + ruler: {YOUR_GCS_BUCKET} + admin: {YOUR_GCS_BUCKET} + +minio: + enabled: false + +write: + extraEnv: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/gel_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: gel-secrets + mountPath: "/etc/gel_secrets" + extraVolumes: + - name: gel-secrets + secret: + secretName: gel-secrets + items: + - key: license.jwt + path: license.jwt + - key: gcp_service_account.json + path: gcp_service_account.json + +read: + extraEnv: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/gel_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: gel-secrets + mountPath: "/etc/gel_secrets" + extraVolumes: + - name: gel-secrets + secret: + secretName: gel-secrets + items: + - key: license.jwt + path: license.jwt + - key: gcp_service_account.json + path: gcp_service_account.json + +gateway: + extraEnv: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/gel_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: gel-secrets + mountPath: "/etc/gel_secrets" + extraVolumes: + - name: gel-secrets + secret: + secretName: gel-secrets + items: + - key: license.jwt + path: license.jwt + - key: gcp_service_account.json + path: gcp_service_account.json diff --git a/charts/loki/docs/examples/oss/README.md b/charts/loki/docs/examples/oss/README.md new file mode 100644 index 0000000..9a0a410 --- /dev/null +++ b/charts/loki/docs/examples/oss/README.md @@ -0,0 +1,20 @@ +## Introduction +This example gives you an example or getting started overrides value file for deploying Loki (OSS) using the Simple Scalable architecture in GKE and using GCS + +## Installation of Helm Chart +These instructions assume you have already have access to a Kubernetes cluster, GCS Bucket and GCP Service Account which has read/write permissions to that GCS Bucket. + +### Populate Secret Values +Populate the examples/enterprise/enterprise-secrets.yaml so that: +- The gcp_service_account.json secret has the contents of your GCP Service Account JSON key + +Deploy the secrets file to your k8s cluster. + +`kubectl apply -f loki-secrets.yaml` + +### Configure the Helm Chart +Open examples/enterprise/overides-oss-gcs.yaml and replace `{YOUR_GCS_BUCKET}` with the name of your GCS bucket. If there are other things you'd like to configure, view the core [Values.yaml file](https://github.com/grafana/loki/blob/main/production/helm/loki/values.yaml) and override anything else you need to within the overrides-enterprise-gcs.yaml file. + +### Install the Helm chart + +`helm upgrade --install --values {PATH_TO_YOUR_OVERRIDES_YAML_FILE} {YOUR_RELEASE_NAME} grafana/loki-simple-scalable --namespace {KUBERNETES_NAMESPACE}` diff --git a/charts/loki/docs/examples/oss/oss-secrets.yaml b/charts/loki/docs/examples/oss/oss-secrets.yaml new file mode 100644 index 0000000..4fbf5e7 --- /dev/null +++ b/charts/loki/docs/examples/oss/oss-secrets.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: loki-secrets +type: Opaque +stringData: + gcp_service_account.json: | + { + GCP_SERVICE_ACCOUNT_JSON_HERE + } \ No newline at end of file diff --git a/charts/loki/docs/examples/oss/overrides-oss-gcs.yaml b/charts/loki/docs/examples/oss/overrides-oss-gcs.yaml new file mode 100644 index 0000000..3e94f84 --- /dev/null +++ b/charts/loki/docs/examples/oss/overrides-oss-gcs.yaml @@ -0,0 +1,77 @@ +enterprise: + enabled: false + adminApi: + enabled: false + useExternalLicense: false + + config: | + admin_client: + storage: + gcs: + bucket_name: {YOUR_GCS_BUCKET} + auth: + type: trust + auth_enabled: false + cluster_name: loki-logs + +loki: + auth_enabled: false + + commonConfig: + path_prefix: /var/loki + replication_factor: 3 + + storage: + type: gcs + bucketNames: + chunks: {YOUR_GCS_BUCKET} + ruler: {YOUR_GCS_BUCKET} + admin: {YOUR_GCS_BUCKET} + +minio: + enabled: false + +write: + extraEnv: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/loki_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: loki-secrets + mountPath: "/etc/loki_secrets" + extraVolumes: + - name: loki-secrets + secret: + secretName: loki-secrets + items: + - key: gcp_service_account.json + path: gcp_service_account.json + +read: + extraEnv: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/loki_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: loki-secrets + mountPath: "/etc/loki_secrets" + extraVolumes: + - name: loki-secrets + secret: + secretName: loki-secrets + items: + - key: gcp_service_account.json + path: gcp_service_account.json + +gateway: + extraEnv: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/loki_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: loki-secrets + mountPath: "/etc/loki_secrets" + extraVolumes: + - name: loki-secrets + secret: + secretName: loki-secrets + items: + - key: gcp_service_account.json + path: gcp_service_account.json diff --git a/charts/loki/reference.md.gotmpl b/charts/loki/reference.md.gotmpl new file mode 100644 index 0000000..e7cc2d6 --- /dev/null +++ b/charts/loki/reference.md.gotmpl @@ -0,0 +1,52 @@ +--- +title: Helm chart values +menuTitle: Helm chart values +description: Reference for Helm Chart values. +aliases: + - ../../../installation/helm/reference/ +weight: 500 +keywords: [] +--- + + + +# Helm chart values + + + + +This is the generated reference for the Loki Helm Chart values. + +> **Note:** This reference is for the Loki Helm chart version 3.0 or greater. +> If you are using the `grafana/loki-stack` Helm chart from the community repo, +> please refer to the `values.yaml` of the respective Github repository +> [grafana/helm-charts](https://github.com/grafana/helm-charts/tree/main/charts/loki-stack). + + + +{{ define "chart.valuesTableHtml" }} +{{ `{{< responsive-table >}}` }} + + + + + + + + + {{- range .Values }} + + + + + + + {{- end }} + +
KeyTypeDescriptionDefault
{{ .Key }}{{ .Type }}{{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }}{{ template "chart.valueDefaultColumnRender" . }}
+{{ `{{< /responsive-table >}}` }} +{{ end }} + +{{ template "chart.valuesTableHtml" . }} + + diff --git a/charts/loki/scenarios/README.md b/charts/loki/scenarios/README.md new file mode 100644 index 0000000..a69d8b2 --- /dev/null +++ b/charts/loki/scenarios/README.md @@ -0,0 +1,82 @@ +# Loki Helm Scenarios + +These scenarios are used by Github Workflow: [Publish Rendered Helm Chart Diff](../../../../.github/workflows/helm-diff-ci.yml). + +Each scenario is used in a different job execution that will be used to deploy loki inside a K3D cluster in our github action workflow. + +We deploy the scenario with the latest release and then we execute a helm diff with the current version in the workspace, the diff between the release deployed will be posted in the pull request inside a comment like [this](https://github.com/grafana/loki/pull/15734#issuecomment-2592439539) making clear to review. + +>*NOTE*: the helm diff output file will be available for each scenario inside github action to download for 2 days, after this you may need to re-run the job if you would like to download the output files. + +## Add new scenario to the CI + +To add a new scenario in the CI, you would just add a new entry to the matrix configuration: + +``` +strategy: + matrix: + scenario: + - name: New Scenario + values_file: new-scenario-values.yaml + use_k3d: true # or false depending on requirements +``` + +## Run scenarios locally + +All this process that we run in the CI can be done locally, the following steps would explain how. + +## Requirements + +To run locally you will need the following tools in your local environment + +* k3d or any kubernetes cluster +* helm +* [helm-diff plugin](https://github.com/databus23/helm-diff) + +## Run + +Make sure that you are pointing to the kubernetes cluster that you want to apply the chart and validate. + +Create a `${scenario}-values.yaml` file with the configuration that you would like to validate. + +Deploy in your kubernetes cluster the latest released version of the helm chart with your config file: + +```shell + helm install --create-namespace loki-release grafana/loki -f ${scenario}-values.yaml +``` + + Then run the helm diff plugin to compare the local helm chart to see the upgrade changes that will happen: + +```shell + HELM_DIFF_USE_UPGRADE_DRY_RUN: true helm diff upgrade loki-release -f ${scenario}-values.yaml production/helm/loki +``` + +The helm diff plugin will compare all manifests that are created in your local development kubernetes cluster and the generated by helm upgrade operation, the output will be printed in your terminal. + +### Configs for CSP specific + +To compare the changes specifically for a cloud provider the process is similar, the main difference that you will need to have access to the kubernetes cluster with the right permissions inside the cloud provider. + +In case that is not possible, the quick validation can be done in a different way, instead of deploy to the kubernetes cluster, we generate the manifests with helm like this: + +```shell + helm template loki-release grafana/loki -f ${scenario}-values.yaml > release-manifest.yaml +``` + +Then we make the same process with local chart version + +```shell + helm template loki-release production/helm/loki -f ${scenario}-values.yaml > current-manifest.yaml +``` + +As the last step you need to run a diff between both files: + +```shell + diff current-manifest.yaml release-manifest.yaml +``` + +### Known Issues + +* The Github Action won't be able to post the diff comment if the PR is coming from a fork, because of permissions the workflow run from a fork is not able to write in the PR content. + + In this case, to review the output we recommend to download the artifacts in the workflow run and check the outputs. diff --git a/charts/loki/scenarios/default-single-binary-values.yaml b/charts/loki/scenarios/default-single-binary-values.yaml new file mode 100644 index 0000000..78a1f11 --- /dev/null +++ b/charts/loki/scenarios/default-single-binary-values.yaml @@ -0,0 +1,71 @@ +--- +loki: + schemaConfig: + configs: + - from: 2024-04-01 + store: tsdb + object_store: s3 + schema: v13 + index: + prefix: loki_index_ + period: 24h + ingester: + chunk_encoding: snappy + tracing: + enabled: true + querier: + # Default is 4, if you have enough memory and CPU you can increase, reduce if OOMing + max_concurrent: 4 + +#gateway: +# ingress: +# enabled: true +# hosts: +# - host: FIXME +# paths: +# - path: / +# pathType: Prefix + +deploymentMode: Distributed + +ingester: + replicas: 3 +querier: + replicas: 3 + maxUnavailable: 2 +queryFrontend: + replicas: 2 + maxUnavailable: 1 +queryScheduler: + replicas: 2 +distributor: + replicas: 3 + maxUnavailable: 2 +compactor: + replicas: 1 +indexGateway: + replicas: 2 + maxUnavailable: 1 + +# optional experimental components +bloomPlanner: + replicas: 0 +bloomBuilder: + replicas: 0 +bloomGateway: + replicas: 0 + +# Enable minio for storage +minio: + enabled: true + +# Zero out replica counts of other deployment modes +backend: + replicas: 0 +read: + replicas: 0 +write: + replicas: 0 + +singleBinary: + replicas: 0 diff --git a/charts/loki/scenarios/default-values.yaml b/charts/loki/scenarios/default-values.yaml new file mode 100644 index 0000000..a79baee --- /dev/null +++ b/charts/loki/scenarios/default-values.yaml @@ -0,0 +1,16 @@ +--- +loki: + commonConfig: + replication_factor: 1 + useTestSchema: true + storage: + bucketNames: + chunks: chunks + ruler: ruler + admin: admin +read: + replicas: 1 +write: + replicas: 1 +backend: + replicas: 1 diff --git a/charts/loki/scenarios/ingress-values.yaml b/charts/loki/scenarios/ingress-values.yaml new file mode 100644 index 0000000..ff5ff1e --- /dev/null +++ b/charts/loki/scenarios/ingress-values.yaml @@ -0,0 +1,30 @@ +--- +gateway: + ingress: + enabled: true + annotations: {} + hosts: + - host: gateway.loki.example.com + paths: + - path: / + pathType: Prefix +loki: + commonConfig: + replication_factor: 1 + useTestSchema: true + storage: + bucketNames: + chunks: chunks + ruler: ruler + admin: admin +read: + replicas: 1 +write: + replicas: 1 +backend: + replicas: 1 +monitoring: + lokiCanary: + enabled: false +test: + enabled: false diff --git a/charts/loki/scenarios/legacy-monitoring-values.yaml b/charts/loki/scenarios/legacy-monitoring-values.yaml new file mode 100644 index 0000000..ad520e5 --- /dev/null +++ b/charts/loki/scenarios/legacy-monitoring-values.yaml @@ -0,0 +1,27 @@ +--- +loki: + commonConfig: + replication_factor: 1 + useTestSchema: true + storage: + bucketNames: + chunks: chunks + ruler: ruler + admin: admin +read: + replicas: 1 +write: + replicas: 1 +backend: + replicas: 1 +monitoring: + enabled: true + selfMonitoring: + enabled: true + grafanaAgent: + installOperator: true + serviceMonitor: + labels: + release: "prometheus" +test: + prometheusAddress: "http://prometheus-kube-prometheus-prometheus.prometheus.svc.cluster.local.:9090" diff --git a/charts/loki/scenarios/simple-scalable-aws-kube-irsa-values.yaml b/charts/loki/scenarios/simple-scalable-aws-kube-irsa-values.yaml new file mode 100644 index 0000000..28c6c3b --- /dev/null +++ b/charts/loki/scenarios/simple-scalable-aws-kube-irsa-values.yaml @@ -0,0 +1,67 @@ +loki: + # -- Storage config. Providing this will automatically populate all necessary storage configs in the templated config. + storage: + # Loki requires a bucket for chunks and the ruler. GEL requires a third bucket for the admin API. + # Please provide these values if you are using object storage. + bucketNames: + chunks: aws-s3-chunks-bucket + ruler: aws-s3-ruler-bucket + admin: aws-s3-admin-bucket + type: s3 + s3: + region: eu-central-1 + # -- Check https://grafana.com/docs/loki/latest/configuration/#schema_config for more info on how to configure schemas + schemaConfig: + configs: + - from: "2023-09-19" + index: + period: 1d + prefix: tsdb_index_ + object_store: s3 + schema: v13 + store: tsdb +###################################################################################################################### +# +# Enterprise Loki Configs +# +###################################################################################################################### + +# -- Configuration for running Enterprise Loki +enterprise: + # Enable enterprise features, license must be provided + enabled: true + # -- Grafana Enterprise Logs license + license: + contents: "content of licence" + tokengen: + annotations: { + eks.amazonaws.com/role-arn: arn:aws:iam::2222222:role/test-role + } + # -- Configuration for `provisioner` target + provisioner: + # -- Additional annotations for the `provisioner` Job + annotations: { + eks.amazonaws.com/role-arn: arn:aws:iam::2222222:role/test-role + } +###################################################################################################################### +# +# Service Accounts and Kubernetes RBAC +# +###################################################################################################################### +serviceAccount: + # -- Annotations for the service account + annotations: + eks.amazonaws.com/role-arn: arn:aws:iam::2222222:role/test-role + +# Configuration for the write pod(s) +write: + persistence: + storageClass: gp2 +# -- Configuration for the read pod(s) +read: + persistence: + storageClass: gp2 +# -- Configuration for the backend pod(s) +backend: + persistence: + storageClass: gp2 diff --git a/charts/loki/scenarios/simple-thanos-values.yaml b/charts/loki/scenarios/simple-thanos-values.yaml new file mode 100644 index 0000000..814b1e4 --- /dev/null +++ b/charts/loki/scenarios/simple-thanos-values.yaml @@ -0,0 +1,53 @@ +--- +loki: + commonConfig: + replication_factor: 1 + useTestSchema: true + + storage: + type: s3 + + use_thanos_objstore: true + + object_store: + type: s3 + + s3: + access_key_id: thanos-minio + secret_access_key: thanos-minio123 + region: us-east-1 + insecure: true + endpoint: http://minio.minio.svc.cluster.local:9000 + http: + tls_config: + insecure_skip_verify: true + + # GCS configuration (when type is "GCS") + gcs: + bucket_name: test-gcs # Name of the bucket + service_account: service-account-test.json # Optional service account JSON + + # Azure configuration (when type is "AZURE") + azure: + account_name: azure-test # Storage account name + account_key: 1234567890 # Optional storage account key + + bucketNames: + chunks: chunks_thanos + ruler: ruler_thanos + admin: admin_thanos + +enterprise: + enabled: true + adminApi: + enabled: true + +minio: + enabled: true + +read: + replicas: 1 +write: + replicas: 1 +backend: + replicas: 1 diff --git a/charts/loki/simple-scalable-values.yaml b/charts/loki/simple-scalable-values.yaml new file mode 100644 index 0000000..78132b6 --- /dev/null +++ b/charts/loki/simple-scalable-values.yaml @@ -0,0 +1,63 @@ +--- +loki: + schemaConfig: + configs: + - from: 2024-04-01 + store: tsdb + object_store: s3 + schema: v13 + index: + prefix: loki_index_ + period: 24h + ingester: + chunk_encoding: snappy + tracing: + enabled: true + querier: + # Default is 4, if you have enough memory and CPU you can increase, reduce if OOMing + max_concurrent: 4 + +#gateway: +# ingress: +# enabled: true +# hosts: +# - host: FIXME +# paths: +# - path: / +# pathType: Prefix + +deploymentMode: SimpleScalable + +backend: + replicas: 3 +read: + replicas: 3 +write: + replicas: 3 + +# Enable minio for storage +minio: + enabled: true + +# Zero out replica counts of other deployment modes +singleBinary: + replicas: 0 + +ingester: + replicas: 0 +querier: + replicas: 0 +queryFrontend: + replicas: 0 +queryScheduler: + replicas: 0 +distributor: + replicas: 0 +compactor: + replicas: 0 +indexGateway: + replicas: 0 +bloomCompactor: + replicas: 0 +bloomGateway: + replicas: 0 diff --git a/charts/loki/single-binary-values.yaml b/charts/loki/single-binary-values.yaml new file mode 100644 index 0000000..584f0fb --- /dev/null +++ b/charts/loki/single-binary-values.yaml @@ -0,0 +1,79 @@ +--- +loki: + commonConfig: + replication_factor: 1 + schemaConfig: + configs: + - from: 2024-04-01 + store: tsdb + object_store: s3 + schema: v13 + index: + prefix: loki_index_ + period: 24h + ingester: + chunk_encoding: snappy + tracing: + enabled: true + querier: + # Default is 4, if you have enough memory and CPU you can increase, reduce if OOMing + max_concurrent: 2 + +#gateway: +# ingress: +# enabled: true +# hosts: +# - host: FIXME +# paths: +# - path: / +# pathType: Prefix + +deploymentMode: SingleBinary +singleBinary: + replicas: 1 + resources: + limits: + cpu: 3 + memory: 4Gi + requests: + cpu: 2 + memory: 2Gi + extraEnv: + # Keep a little bit lower than memory limits + - name: GOMEMLIMIT + value: 3750MiB + +chunksCache: + # default is 500MB, with limited memory keep this smaller + writebackSizeLimit: 10MB + +# Enable minio for storage +minio: + enabled: true + +# Zero out replica counts of other deployment modes +backend: + replicas: 0 +read: + replicas: 0 +write: + replicas: 0 + +ingester: + replicas: 0 +querier: + replicas: 0 +queryFrontend: + replicas: 0 +queryScheduler: + replicas: 0 +distributor: + replicas: 0 +compactor: + replicas: 0 +indexGateway: + replicas: 0 +bloomCompactor: + replicas: 0 +bloomGateway: + replicas: 0 diff --git a/charts/loki/src/.yamllint.yaml b/charts/loki/src/.yamllint.yaml new file mode 100644 index 0000000..19e5933 --- /dev/null +++ b/charts/loki/src/.yamllint.yaml @@ -0,0 +1,4 @@ +--- +rules: + quoted-strings: + required: true diff --git a/charts/loki/src/alerts.yaml.tpl b/charts/loki/src/alerts.yaml.tpl new file mode 100644 index 0000000..0aa37b7 --- /dev/null +++ b/charts/loki/src/alerts.yaml.tpl @@ -0,0 +1,78 @@ +--- +groups: + - name: "loki_alerts" + rules: +{{- if not (.Values.monitoring.rules.disabled.LokiRequestErrors | default false) }} + - alert: "LokiRequestErrors" + annotations: + message: | + {{`{{`}} $labels.job {{`}}`}} {{`{{`}} $labels.route {{`}}`}} is experiencing {{`{{`}} printf "%.2f" $value {{`}}`}}% errors. + expr: | + 100 * sum(rate(loki_request_duration_seconds_count{status_code=~"5.."}[2m])) by (namespace, job, route) + / + sum(rate(loki_request_duration_seconds_count[2m])) by (namespace, job, route) + > 10 + for: "15m" + labels: + severity: "critical" +{{- if .Values.monitoring.rules.additionalRuleLabels }} +{{ toYaml .Values.monitoring.rules.additionalRuleLabels | indent 10 }} +{{- end }} +{{- end }} +{{- if not (.Values.monitoring.rules.disabled.LokiRequestPanics | default false) }} + - alert: "LokiRequestPanics" + annotations: + message: | + {{`{{`}} $labels.job {{`}}`}} is experiencing {{`{{`}} printf "%.2f" $value {{`}}`}}% increase of panics. + expr: | + sum(increase(loki_panic_total[10m])) by (namespace, job) > 0 + labels: + severity: "critical" +{{- if .Values.monitoring.rules.additionalRuleLabels }} +{{ toYaml .Values.monitoring.rules.additionalRuleLabels | indent 10 }} +{{- end }} +{{- end }} +{{- if not (.Values.monitoring.rules.disabled.LokiRequestLatency | default false) }} + - alert: "LokiRequestLatency" + annotations: + message: | + {{`{{`}} $labels.job {{`}}`}} {{`{{`}} $labels.route {{`}}`}} is experiencing {{`{{`}} printf "%.2f" $value {{`}}`}}s 99th percentile latency. + expr: | + namespace_job_route:loki_request_duration_seconds:99quantile{route!~"(?i).*tail.*"} > 1 + for: "15m" + labels: + severity: "critical" +{{- if .Values.monitoring.rules.additionalRuleLabels }} +{{ toYaml .Values.monitoring.rules.additionalRuleLabels | indent 10 }} +{{- end }} +{{- end }} +{{- if not (.Values.monitoring.rules.disabled.LokiTooManyCompactorsRunning | default false) }} + - alert: "LokiTooManyCompactorsRunning" + annotations: + message: | + {{`{{`}} $labels.cluster {{`}}`}} {{`{{`}} $labels.namespace {{`}}`}} has had {{`{{`}} printf "%.0f" $value {{`}}`}} compactors running for more than 5m. Only one compactor should run at a time. + expr: | + sum(loki_boltdb_shipper_compactor_running) by (cluster, namespace) > 1 + for: "5m" + labels: + severity: "warning" +{{- if .Values.monitoring.rules.additionalRuleLabels }} +{{ toYaml .Values.monitoring.rules.additionalRuleLabels | indent 10 }} +{{- end }} +{{- end }} +{{- if not (.Values.monitoring.rules.disabled.LokiCanaryLatency | default false) }} + - name: "loki_canaries_alerts" + rules: + - alert: "LokiCanaryLatency" + annotations: + message: | + {{`{{`}} $labels.job {{`}}`}} is experiencing {{`{{`}} printf "%.2f" $value {{`}}`}}s 99th percentile latency. + expr: | + histogram_quantile(0.99, sum(rate(loki_canary_response_latency_seconds_bucket[5m])) by (le, namespace, job)) > 5 + for: "15m" + labels: + severity: "warning" +{{- if .Values.monitoring.rules.additionalRuleLabels }} +{{ toYaml .Values.monitoring.rules.additionalRuleLabels | indent 10 }} +{{- end }} +{{- end }} diff --git a/charts/loki/src/dashboards/loki-chunks.json b/charts/loki/src/dashboards/loki-chunks.json new file mode 100644 index 0000000..bec1997 --- /dev/null +++ b/charts/loki/src/dashboards/loki-chunks.json @@ -0,0 +1,1336 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(loki_ingester_memory_chunks{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "series", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Series", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(loki_ingester_memory_chunks{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}) / sum(loki_ingester_memory_streams{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "chunks", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Chunks per series", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Active Series / Chunks", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_utilization_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_ingester_chunk_utilization_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_ingester_chunk_utilization_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) * 1 / sum(rate(loki_ingester_chunk_utilization_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Utilization", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_age_seconds_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_ingester_chunk_age_seconds_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_ingester_chunk_age_seconds_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) * 1e3 / sum(rate(loki_ingester_chunk_age_seconds_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Age", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Flush Stats", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_entries_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_ingester_chunk_entries_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_ingester_chunk_entries_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) * 1 / sum(rate(loki_ingester_chunk_entries_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Log Entries Per Chunk", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_chunk_store_index_entries_per_chunk_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m])) / sum(rate(loki_chunk_store_index_entries_per_chunk_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Index Entries", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Index Entries Per Chunk", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Flush Stats", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "loki_ingester_flush_queue_length{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"} or cortex_ingester_flush_queue_length{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Queue Length", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { + "1xx": "#EAB839", + "2xx": "#7EB26D", + "3xx": "#6ED0E0", + "4xx": "#EF843C", + "5xx": "#E24D42", + "error": "#E24D42", + "success": "#7EB26D" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_ingester_chunk_age_seconds_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{status}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Flush Rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Flush Stats", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 9, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_ingester_chunks_flushed_total{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Chunks Flushed/Second", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (reason) (rate(loki_ingester_chunks_flushed_total{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) / ignoring(reason) group_left sum(rate(loki_ingester_chunks_flushed_total{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{reason}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Chunk Flush Reason", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": 1, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": 1, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Flush Stats", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "cards": { + "cardPadding": null, + "cardRound": null + }, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateSpectral", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": "$datasource", + "heatmap": { }, + "hideZeroBuckets": false, + "highlightCards": true, + "id": 11, + "legend": { + "show": true + }, + "span": 12, + "targets": [ + { + "expr": "sum by (le) (rate(loki_ingester_chunk_utilization_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))", + "format": "heatmap", + "intervalFactor": 2, + "legendFormat": "{{le}}", + "refId": "A" + } + ], + "title": "Chunk Utilization", + "tooltip": { + "show": true, + "showHistogram": true + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "xBucketNumber": null, + "xBucketSize": null, + "yAxis": { + "decimals": 0, + "format": "percentunit", + "show": true, + "splitFactor": null + }, + "yBucketBound": "auto" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Utilization", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "cards": { + "cardPadding": null, + "cardRound": null + }, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateSpectral", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": "$datasource", + "heatmap": { }, + "hideZeroBuckets": false, + "highlightCards": true, + "id": 12, + "legend": { + "show": true + }, + "span": 12, + "targets": [ + { + "expr": "sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)", + "format": "heatmap", + "intervalFactor": 2, + "legendFormat": "{{le}}", + "refId": "A" + } + ], + "title": "Chunk Size Bytes", + "tooltip": { + "show": true, + "showHistogram": true + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "xBucketNumber": null, + "xBucketSize": null, + "yAxis": { + "decimals": 0, + "format": "bytes", + "show": true, + "splitFactor": null + }, + "yBucketBound": "auto" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Utilization", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 13, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[1m])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "p99", + "legendLink": null, + "step": 10 + }, + { + "expr": "histogram_quantile(0.90, sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[1m])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "p90", + "legendLink": null, + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[1m])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "p50", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Chunk Size Quantiles", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Utilization", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.5, sum(rate(loki_ingester_chunk_bounds_hours_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "p50", + "legendLink": null, + "step": 10 + }, + { + "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_bounds_hours_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "p99", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum(rate(loki_ingester_chunk_bounds_hours_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m])) / sum(rate(loki_ingester_chunk_bounds_hours_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "avg", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Chunk Duration hours (end-start)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Duration", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Chunks", + "uid": "chunks", + "version": 0 + } \ No newline at end of file diff --git a/charts/loki/src/dashboards/loki-deletion.json b/charts/loki/src/dashboards/loki-deletion.json new file mode 100644 index 0000000..84bfee6 --- /dev/null +++ b/charts/loki/src/dashboards/loki-deletion.json @@ -0,0 +1,632 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "100px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "format": "none", + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(loki_compactor_pending_delete_requests_count{cluster=~\"$cluster\", namespace=~\"$namespace\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Number of Pending Requests", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "singlestat", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "format": "dtdurations", + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max(loki_compactor_oldest_pending_delete_request_age_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Oldest Pending Request Age", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "singlestat", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Headlines", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(loki_compactor_delete_requests_received_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[1d]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "received", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Delete Requests Received / Day", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(loki_compactor_delete_requests_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[1d]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "processed", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Delete Requests Processed / Day", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Churn", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(loki_compactor_load_pending_requests_attempts_total{status=\"fail\", cluster=~\"$cluster\", namespace=~\"$namespace\"}[1h]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "failures", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Failures in Loading Delete Requests / Hour", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Failures", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_compactor_deleted_lines{cluster=~\"$cluster\",job=~\"$namespace/(loki|enterprise-logs)-read\"}[$__rate_interval])) by (user)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{user}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Lines Deleted / Sec", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Deleted lines", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Deletion", + "uid": "deletion", + "version": 0 + } \ No newline at end of file diff --git a/charts/loki/src/dashboards/loki-logs.json b/charts/loki/src/dashboards/loki-logs.json new file mode 100644 index 0000000..0f113cf --- /dev/null +++ b/charts/loki/src/dashboards/loki-logs.json @@ -0,0 +1,1073 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": 8, + "iteration": 1583185057230, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 35, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(go_goroutines{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\"})", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "goroutines", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 3, + "y": 0 + }, + "hiddenSeries": false, + "id": 41, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(go_gc_duration_seconds{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\"}) by (quantile)", + "legendFormat": "{{quantile}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "gc duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 6, + "y": 0 + }, + "hiddenSeries": false, + "id": 36, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_cpu_usage_seconds_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "cpu", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 9, + "y": 0 + }, + "hiddenSeries": false, + "id": 40, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\"})", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "working set", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 12, + "y": 0 + }, + "hiddenSeries": false, + "id": 38, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_network_transmit_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "tx", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 15, + "y": 0 + }, + "hiddenSeries": false, + "id": 39, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_network_receive_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "rx", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 18, + "y": 0 + }, + "hiddenSeries": false, + "id": 37, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "increase(kube_pod_container_status_last_terminated_reason{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\"}[30m]) > 0", + "legendFormat": "{{reason}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "restarts", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 21, + "y": 0 + }, + "hiddenSeries": false, + "id": 42, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(promtail_custom_bad_words_total{cluster=\"$cluster\", exported_namespace=\"$namespace\", exported_pod=~\"$deployment.*\", exported_pod=~\"$pod\", container=~\"$container\"}[5m])) by (level)", + "legendFormat": "{{level}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "bad words", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$logs", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 4 + }, + "hiddenSeries": false, + "id": 31, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "warn", + "color": "#FF780A" + }, + { + "alias": "error", + "color": "#E02F44" + }, + { + "alias": "info", + "color": "#56A64B" + }, + { + "alias": "debug", + "color": "#3274D9" + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate({cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\" } |logfmt| level=~\"$level\" |= \"$filter\" [5m])) by (level)", + "intervalFactor": 3, + "legendFormat": "{{level}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Log Rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": false, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "$logs", + "gridPos": { + "h": 19, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 29, + "maxDataPoints": "", + "options": { + "showLabels": false, + "showTime": true, + "sortOrder": "Descending", + "wrapLogMessage": true + }, + "targets": [ + { + "expr": "{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\"} | logfmt | level=~\"$level\" |= \"$filter\"", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Logs", + "type": "logs" + } + ], + "refresh": "10s", + "rows": [ ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "hide": 0, + "label": null, + "name": "logs", + "options": [ ], + "query": "loki", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "deployment", + "options": [ ], + "query": "label_values(kube_deployment_created{cluster=\"$cluster\", namespace=\"$namespace\"}, deployment)", + "refresh": 0, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "pod", + "options": [ ], + "query": "label_values(kube_pod_container_info{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\"}, pod)", + "refresh": 0, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "container", + "options": [ ], + "query": "label_values(kube_pod_container_info{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\", pod=~\"$deployment.*\"}, container)", + "refresh": 0, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "selected": true, + "text": "", + "value": "" + }, + "hide": 0, + "includeAll": false, + "label": "", + "multi": true, + "name": "level", + "options": [ + { + "selected": false, + "text": "debug", + "value": "debug" + }, + { + "selected": false, + "text": "info", + "value": "info" + }, + { + "selected": false, + "text": "warn", + "value": "warn" + }, + { + "selected": false, + "text": "error", + "value": "error" + } + ], + "query": "debug,info,warn,error", + "refresh": 0, + "type": "custom" + }, + { + "current": { + "selected": false, + "text": "", + "value": "" + }, + "label": "LogQL Filter", + "name": "filter", + "query": "", + "type": "textbox" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Logs", + "uid": "logs", + "version": 0 + } \ No newline at end of file diff --git a/charts/loki/src/dashboards/loki-mixin-recording-rules.json b/charts/loki/src/dashboards/loki-mixin-recording-rules.json new file mode 100644 index 0000000..fe49ec7 --- /dev/null +++ b/charts/loki/src/dashboards/loki-mixin-recording-rules.json @@ -0,0 +1,657 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [ ], + "type": "dashboard" + }, + "type": "dashboard" + }, + { + "datasource": "${datasource}", + "enable": false, + "expr": "sum by (tenant) (changes(loki_ruler_wal_prometheus_tsdb_wal_truncations_total{tenant=~\"${tenant}\"}[$__rate_interval]))", + "iconColor": "red", + "name": "WAL Truncations", + "target": { + "queryType": "Azure Monitor", + "refId": "Anno" + }, + "titleFormat": "{{tenant}}" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1635347545534, + "links": [ ], + "liveNow": false, + "panels": [ + { + "datasource": "${datasource}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ ], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 1 + } + ] + } + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 2, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "8.3.0-38205pre", + "targets": [ + { + "datasource": "${datasource}", + "exemplar": false, + "expr": "sum(loki_ruler_wal_appender_ready) by (pod, tenant) == 0", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Appenders Not Ready", + "type": "stat" + }, + { + "datasource": "${datasource}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 11, + "x": 2, + "y": 0 + }, + "id": 4, + "options": { + "legend": { + "calcs": [ ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "exemplar": true, + "expr": "sum(rate(loki_ruler_wal_samples_appended_total{tenant=~\"${tenant}\"}[$__rate_interval])) by (tenant) > 0", + "interval": "", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "title": "Samples Appended to WAL per Second", + "type": "timeseries" + }, + { + "datasource": "${datasource}", + "description": "Series are unique combinations of labels", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 11, + "x": 13, + "y": 0 + }, + "id": 5, + "options": { + "legend": { + "calcs": [ ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "exemplar": true, + "expr": "sum(rate(loki_ruler_wal_storage_created_series_total{tenant=~\"${tenant}\"}[$__rate_interval])) by (tenant) > 0", + "interval": "", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "title": "Series Created per Second", + "type": "timeseries" + }, + { + "datasource": "${datasource}", + "description": "Difference between highest timestamp appended to WAL and highest timestamp successfully written to remote storage", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 6, + "options": { + "legend": { + "calcs": [ ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "exemplar": true, + "expr": "loki_ruler_wal_prometheus_remote_storage_highest_timestamp_in_seconds{tenant=~\"${tenant}\"}\n- on (tenant)\n (\n loki_ruler_wal_prometheus_remote_storage_queue_highest_sent_timestamp_seconds{tenant=~\"${tenant}\"}\n or vector(0)\n )", + "interval": "", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "title": "Write Behind", + "type": "timeseries" + }, + { + "datasource": "${datasource}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 10 + }, + "id": 7, + "options": { + "legend": { + "calcs": [ ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "exemplar": true, + "expr": "sum(rate(loki_ruler_wal_prometheus_remote_storage_samples_total{tenant=~\"${tenant}\"}[$__rate_interval])) by (tenant) > 0", + "interval": "", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "title": "Samples Sent per Second", + "type": "timeseries" + }, + { + "datasource": "${datasource}", + "description": "\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 20 + }, + "id": 8, + "options": { + "legend": { + "calcs": [ ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "exemplar": true, + "expr": "sum by (tenant) (loki_ruler_wal_disk_size{tenant=~\"${tenant}\"})", + "interval": "", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "title": "WAL Disk Size", + "type": "timeseries" + }, + { + "datasource": "${datasource}", + "description": "Some number of pending samples is expected, but if remote-write is failing this value will remain high", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 20 + }, + "id": 9, + "options": { + "legend": { + "calcs": [ ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "exemplar": true, + "expr": "max(loki_ruler_wal_prometheus_remote_storage_samples_pending{tenant=~\"${tenant}\"}) by (tenant,pod) > 0", + "interval": "", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "title": "Pending Samples", + "type": "timeseries" + } + ], + "schemaVersion": 31, + "style": "dark", + "tags": [ ], + "templating": { + "list": [ + { + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": "Datasource", + "multi": false, + "name": "datasource", + "options": [ ], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": null, + "datasource": "${datasource}", + "definition": "label_values(loki_ruler_wal_samples_appended_total, tenant)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": "Tenant", + "multi": true, + "name": "tenant", + "options": [ ], + "query": { + "query": "label_values(loki_ruler_wal_samples_appended_total, tenant)", + "refId": "StandardVariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { }, + "timezone": "", + "title": "Recording Rules", + "uid": "2xKA_ZK7k", + "version": 9, + "weekStart": "" + } \ No newline at end of file diff --git a/charts/loki/src/dashboards/loki-operational.json b/charts/loki/src/dashboards/loki-operational.json new file mode 100644 index 0000000..b69db23 --- /dev/null +++ b/charts/loki/src/dashboards/loki-operational.json @@ -0,0 +1,6173 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": 68, + "iteration": 1588704280892, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "panels": [ + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 17, + "panels": [ ], + "targets": [ ], + "title": "Main", + "type": "row" + }, + { + "aliasColors": { + "5xx": "red" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 4, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\nlabel_replace(\n label_replace(\n rate(loki_request_duration_seconds_count{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\"}[5m]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n\"status\", \"${1}\", \"status_code\", \"([a-z]+)\")\n)", + "legendFormat": "{{status}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Queries/Second", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 10, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "5xx": "red" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 4, + "x": 4, + "y": 1 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\nlabel_replace(\n label_replace(\n rate(loki_request_duration_seconds_count{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push\"}[5m]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n\"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))", + "legendFormat": "{{status}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Pushes/Second", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 10, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 4, + "x": 12, + "y": 1 + }, + "hiddenSeries": false, + "id": 2, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "topk(10, sum(rate(loki_distributor_lines_received_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (tenant))", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Lines Per Tenant (top 10)", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 4, + "x": 16, + "y": 1 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "topk(10, sum(rate(loki_distributor_bytes_received_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (tenant)) / 1024 / 1024", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "MBs Per Tenant (Top 10)", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 4, + "x": 20, + "y": 1 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "increase(kube_pod_container_status_restarts_total{cluster=\"$cluster\", namespace=\"$namespace\"}[10m]) > 0", + "hide": false, + "interval": "", + "legendFormat": "{{container}}-{{pod}}", + "refId": "B" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Container Restarts", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 6 + }, + "hiddenSeries": false, + "id": 9, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".99", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.75, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".9", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.5, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".5", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Push Latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 6 + }, + "hiddenSeries": false, + "id": 12, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".99", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.9, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".9", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.5, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".5", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Distributor Latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 6 + }, + "hiddenSeries": false, + "id": 71, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", status_code!~\"5[0-9]{2}\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[5m])) by (route)", + "interval": "", + "legendFormat": "{{route}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Distributor Success Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "decimals": null, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": "1", + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 11 + }, + "hiddenSeries": false, + "id": 13, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=\"/logproto.Pusher/Push\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".99", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.9, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=\"/logproto.Pusher/Push\", cluster=~\"$cluster\"})) * 1e3", + "hide": false, + "legendFormat": ".9", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.5, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=\"/logproto.Pusher/Push\", cluster=~\"$cluster\"})) * 1e3", + "hide": false, + "legendFormat": ".5", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Ingester Latency Write", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 11 + }, + "hiddenSeries": false, + "id": 72, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", status_code!~\"5[0-9]{2}\", route=\"/logproto.Pusher/Push\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", route=\"/logproto.Pusher/Push\"}[5m])) by (route)", + "interval": "", + "legendFormat": "{{route}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Ingester Success Rate Write", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "decimals": null, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": "1", + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 16 + }, + "hiddenSeries": false, + "id": 10, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"}))", + "legendFormat": "{{route}}-.99", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.9, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"}))", + "legendFormat": "{{route}}-.9", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.5, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"}))", + "legendFormat": "{{route}}-.5", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Query Latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 16 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"})) * 1e3", + "legendFormat": ".99-{{route}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.9, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"})) * 1e3", + "legendFormat": ".9-{{route}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.5, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"})) * 1e3", + "legendFormat": ".5-{{route}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Querier Latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 16 + }, + "hiddenSeries": false, + "id": 73, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\", status_code!~\"5[0-9]{2}\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\"}[5m])) by (route)", + "interval": "", + "legendFormat": "{{route}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Querier Success Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "decimals": null, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": "1", + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 21 + }, + "hiddenSeries": false, + "id": 15, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\", cluster=\"$cluster\"})) * 1e3", + "legendFormat": ".99-{{route}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.9, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\", cluster=\"$cluster\"})) * 1e3", + "legendFormat": ".9-{{route}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.5, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\", cluster=\"$cluster\"})) * 1e3", + "legendFormat": ".5-{{route}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Ingester Latency Read", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 21 + }, + "hiddenSeries": false, + "id": 74, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", status_code!~\"5[0-9]{2}\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\"}[5m])) by (route)", + "interval": "", + "legendFormat": "{{route}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Ingester Success Rate Read", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "decimals": null, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": "1", + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 26 + }, + "id": 110, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 27 + }, + "hiddenSeries": false, + "id": 112, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "topk(10,sum by (tenant, reason) (rate(loki_discarded_samples_total{cluster=\"$cluster\",namespace=\"$namespace\"}[1m])))", + "interval": "", + "legendFormat": "{{ tenant }} - {{ reason }}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Discarded Lines", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "columns": [ ], + "datasource": "$datasource", + "fontSize": "100%", + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 27 + }, + "id": 113, + "pageSize": null, + "panels": [ ], + "showHeader": true, + "sort": { + "col": 3, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "tenant", + "thresholds": [ ], + "type": "string", + "unit": "short" + }, + { + "alias": "", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "reason", + "thresholds": [ ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "align": "right", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ ], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "expr": "topk(10, sum by (tenant, reason) (sum_over_time(increase(loki_discarded_samples_total{cluster=\"$cluster\",namespace=\"$namespace\"}[1m])[$__range:1m])))", + "format": "table", + "instant": true, + "interval": "", + "legendFormat": "{{ tenant }} - {{ reason }}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Discarded Lines Per Interval", + "transform": "table", + "type": "table-old" + } + ], + "targets": [ ], + "title": "Limits", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 27 + }, + "id": 23, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 28 + }, + "hiddenSeries": false, + "id": 26, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"(loki|enterprise-logs)-write.*\"}", + "intervalFactor": 3, + "legendFormat": "{{pod}}-{{container}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 28 + }, + "hiddenSeries": false, + "id": 27, + "legend": { + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "go_memstats_heap_inuse_bytes{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"(loki|enterprise-logs)-write.*\"}", + "instant": false, + "intervalFactor": 3, + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Memory Usage", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$logs", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 12, + "x": 12, + "y": 28 + }, + "hiddenSeries": false, + "id": 31, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "{}", + "color": "#C4162A" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate({cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\"} | logfmt | level=\"error\"[1m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Error Log Rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": false, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "$logs", + "gridPos": { + "h": 18, + "w": 12, + "x": 12, + "y": 32 + }, + "id": 29, + "options": { + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": true + }, + "panels": [ ], + "targets": [ + { + "expr": "{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\"} | logfmt | level=\"error\"", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Logs", + "type": "logs" + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 35 + }, + "hiddenSeries": false, + "id": 33, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", status_code!~\"5[0-9]{2}\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[5m])) by (route)", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{route}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Success Rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 35 + }, + "hiddenSeries": false, + "id": 32, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_distributor_ingester_append_failures_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (ingester)", + "intervalFactor": 1, + "legendFormat": "{{ingester}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Append Failures By Ingester", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 42 + }, + "hiddenSeries": false, + "id": 34, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_distributor_bytes_received_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (pod)", + "intervalFactor": 1, + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Bytes Received/Second", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 42 + }, + "hiddenSeries": false, + "id": 35, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_distributor_lines_received_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (pod)", + "intervalFactor": 1, + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Lines Received/Second", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Write Path", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 29 + }, + "id": 104, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 30 + }, + "hiddenSeries": false, + "id": 106, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "topk(10,sum by (tenant) (loki_ingester_memory_streams{cluster=\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\"}))", + "interval": "", + "legendFormat": "{{ tenant }}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Active Streams", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 30 + }, + "hiddenSeries": false, + "id": 108, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "topk(10, sum by (tenant) (rate(loki_ingester_streams_created_total{cluster=\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m]) > 0))", + "interval": "", + "legendFormat": "{{ tenant }}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Streams Created/Sec", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Streams", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 30 + }, + "id": 94, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 31 + }, + "hiddenSeries": false, + "id": 102, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "De-Dupe Ratio", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_ingester_chunks_flushed_total{cluster=\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m]))", + "interval": "", + "legendFormat": "Chunks", + "refId": "A" + }, + { + "expr": "sum(increase(loki_chunk_store_deduped_chunks_total{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m]))/sum(increase(loki_ingester_chunks_flushed_total{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m])) < 1", + "interval": "", + "legendFormat": "De-Dupe Ratio", + "refId": "B" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Chunks Flushed/Sec", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "cards": { + "cardPadding": null, + "cardRound": null + }, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateSpectral", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": "$datasource", + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 31 + }, + "heatmap": { }, + "hideZeroBuckets": false, + "highlightCards": true, + "id": 100, + "legend": { + "show": true + }, + "panels": [ ], + "reverseYBuckets": false, + "targets": [ + { + "expr": "sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m])) by (le)", + "format": "heatmap", + "instant": false, + "interval": "", + "legendFormat": "{{ le }}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Chunk Size Bytes", + "tooltip": { + "show": true, + "showHistogram": false + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "xBucketNumber": null, + "xBucketSize": null, + "yAxis": { + "decimals": 0, + "format": "bytes", + "logBase": 1, + "max": null, + "min": null, + "show": true, + "splitFactor": null + }, + "yBucketBound": "auto", + "yBucketNumber": null, + "yBucketSize": null + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 7, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 39 + }, + "hiddenSeries": false, + "id": 96, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(reason) (rate(loki_ingester_chunks_flushed_total{cluster=~\"$cluster\",job=~\"$namespace/ingester\", namespace=~\"$namespace\"}[$__rate_interval])) / ignoring(reason) group_left sum(rate(loki_ingester_chunks_flushed_total{cluster=~\"$cluster\",job=~\"$namespace/ingester\", namespace=~\"$namespace\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "{{ reason }}" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Chunk Flush Reason %", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": "1", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "cards": { + "cardPadding": null, + "cardRound": null + }, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateSpectral", + "exponent": 0.5, + "max": null, + "min": null, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": "$datasource", + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 39 + }, + "heatmap": { }, + "hideZeroBuckets": true, + "highlightCards": true, + "id": 98, + "legend": { + "show": true + }, + "panels": [ ], + "reverseYBuckets": false, + "targets": [ + { + "expr": "sum by (le) (rate(loki_ingester_chunk_utilization_bucket{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m]))", + "format": "heatmap", + "instant": false, + "interval": "", + "legendFormat": "{{ le }}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Chunk Utilization", + "tooltip": { + "show": true, + "showHistogram": false + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "xBucketNumber": null, + "xBucketSize": null, + "yAxis": { + "decimals": 0, + "format": "percentunit", + "logBase": 1, + "max": null, + "min": null, + "show": true, + "splitFactor": null + }, + "yBucketBound": "auto", + "yBucketNumber": null, + "yBucketSize": null + } + ], + "targets": [ ], + "title": "Chunks", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 31 + }, + "id": 64, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 32 + }, + "hiddenSeries": false, + "id": 68, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"(loki|enterprise-logs)-read.*\"}", + "intervalFactor": 3, + "legendFormat": "{{pod}}-{{container}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 39 + }, + "hiddenSeries": false, + "id": 69, + "legend": { + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "go_memstats_heap_inuse_bytes{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"(loki|enterprise-logs)-read.*\"}", + "instant": false, + "intervalFactor": 3, + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Memory Usage", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$logs", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 3, + "w": 18, + "x": 12, + "y": 32 + }, + "hiddenSeries": false, + "id": 65, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "{}", + "color": "#F2495C" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate({cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\"} | logfmt | level=\"error\"[1m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Error Log Rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": false, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "$logs", + "gridPos": { + "h": 18, + "w": 18, + "x": 12, + "y": 35 + }, + "id": 66, + "options": { + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": true + }, + "panels": [ ], + "targets": [ + { + "expr": "{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\"} | logfmt | level=\"error\"", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Logs", + "type": "logs" + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 46 + }, + "hiddenSeries": false, + "id": 70, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\", status_code!~\"5[0-9]{2}\"}[1m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\"}[1m])) by (route)", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{route}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Success Rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Read Path", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 32 + }, + "id": 52, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 30 + }, + "hiddenSeries": false, + "id": 53, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_memcache_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (method, name, le, container))", + "intervalFactor": 1, + "legendFormat": "{{container}}: .99-{{method}}-{{name}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_memcache_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (method, name, le, container))", + "hide": false, + "legendFormat": "{{container}}: .9-{{method}}-{{name}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_memcache_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (method, name, le, container))", + "hide": false, + "legendFormat": "{{container}}: .5-{{method}}-{{name}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 38 + }, + "hiddenSeries": false, + "id": 54, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_memcache_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, method, name, container)", + "intervalFactor": 1, + "legendFormat": "{{container}}: {{status_code}}-{{method}}-{{name}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Memcached", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 33 + }, + "id": 57, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 31 + }, + "hiddenSeries": false, + "id": 55, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_consul_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".99-{{operation}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_consul_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".9-{{operation}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_consul_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".5-{{operation}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 39 + }, + "hiddenSeries": false, + "id": 58, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_consul_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, status_code, method)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}-{{operation}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Consul", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 34 + }, + "id": 43, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 9 + }, + "hiddenSeries": false, + "id": 41, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/MutateRows\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".9", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/MutateRows\"}[5m])) by (operation, le))", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/MutateRows\"}[5m])) by (operation, le))", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "MutateRows Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 9 + }, + "hiddenSeries": false, + "id": 46, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/ReadRows\"}[5m])) by (operation, le))", + "interval": "", + "intervalFactor": 1, + "legendFormat": "99%", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/ReadRows\"}[5m])) by (operation, le))", + "interval": "", + "legendFormat": "90%", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/ReadRows\"}[5m])) by (operation, le))", + "interval": "", + "legendFormat": "50%", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "ReadRows Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 9 + }, + "hiddenSeries": false, + "id": 44, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable\"}[5m])) by (operation, le))", + "interval": "", + "intervalFactor": 1, + "legendFormat": "99%", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable\"}[5m])) by (operation, le))", + "interval": "", + "legendFormat": "90%", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable\"}[5m])) by (operation, le))", + "interval": "", + "legendFormat": "50%", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "GetTable Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 9 + }, + "hiddenSeries": false, + "id": 45, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".9", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables\"}[5m])) by (operation, le))", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables\"}[5m])) by (operation, le))", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "ListTables Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 16 + }, + "hiddenSeries": false, + "id": 47, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_bigtable_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/MutateRows\"}[5m])) by (status_code)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "MutateRows Status", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 16 + }, + "hiddenSeries": false, + "id": 50, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_bigtable_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/ReadRows\"}[5m])) by (status_code)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "ReadRows Status", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 16 + }, + "hiddenSeries": false, + "id": 48, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_bigtable_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable\"}[5m])) by (status_code)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "GetTable Status", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 16 + }, + "hiddenSeries": false, + "id": 49, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_bigtable_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables\"}[5m])) by (status_code)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "ListTables Status", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Big Table", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 35 + }, + "id": 60, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 33 + }, + "hiddenSeries": false, + "id": 61, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_gcs_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".99-{{operation}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_gcs_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".9-{{operation}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_gcs_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".5-{{operation}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 41 + }, + "hiddenSeries": false, + "id": 62, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_gcs_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}-{{operation}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "GCS", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 36 + }, + "id": 76, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 9 + }, + "id": 82, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(cortex_dynamo_failures_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Failure Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 9 + }, + "id": 83, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(cortex_dynamo_consumed_capacity_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Consumed Capacity Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 9 + }, + "id": 84, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(cortex_dynamo_throttled_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Throttled Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 9 + }, + "id": 85, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(cortex_dynamo_dropped_requests_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Dropped Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 15 + }, + "id": 86, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(cortex_dynamo_query_pages_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])))", + "legendFormat": ".99", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(cortex_dynamo_query_pages_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])))", + "legendFormat": ".9", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(cortex_dynamo_query_pages_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])))", + "legendFormat": ".5", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Query Pages", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 9, + "x": 6, + "y": 15 + }, + "id": 87, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(cortex_dynamo_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".99-{{operation}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(cortex_dynamo_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".9-{{operation}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(cortex_dynamo_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".5-{{operation}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 9, + "x": 15, + "y": 15 + }, + "id": 88, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(cortex_dynamo_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}-{{operation}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Dynamo", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 37 + }, + "id": 78, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 79, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_s3_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".99-{{operation}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_s3_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".9-{{operation}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_s3_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".5-{{operation}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 80, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_s3_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}-{{operation}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "S3", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 37 + }, + "id": 78, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 79, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_azure_blob_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".99-{{operation}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_azure_blob_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".9-{{operation}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_azure_blob_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".5-{{operation}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 80, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_azure_blob_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}-{{operation}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Azure Blob", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 37 + }, + "id": 114, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 115, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".99-{{operation}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".9-{{operation}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".5-{{operation}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 116, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}-{{operation}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "BoltDB Shipper", + "type": "row" + } + ], + "refresh": "10s", + "rows": [ ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "hide": 0, + "label": null, + "name": "logs", + "options": [ ], + "query": "loki", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Operational", + "uid": "operational", + "version": 0 + } diff --git a/charts/loki/src/dashboards/loki-reads-resources.json b/charts/loki/src/dashboards/loki-reads-resources.json new file mode 100644 index 0000000..6fa166f --- /dev/null +++ b/charts/loki/src/dashboards/loki-reads-resources.json @@ -0,0 +1,964 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_cpu_quota{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"} / container_spec_cpu_period{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "CPU", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_memory_limit_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"} > 0)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (workingset)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (go_memstats_heap_inuse_bytes{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-read\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (go heap inuse)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "gridPos": { }, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(instance, pod, device) (rate(node_disk_written_bytes_total[$__rate_interval])) + ignoring(pod) group_right() (label_replace(count by(instance, pod, device) (container_fs_writes_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\", device!~\".*sda.*\"}), \"device\", \"$1\", \"device\", \"/dev/(.*)\") * 0)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}} - {{device}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Writes", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "gridPos": { }, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(instance, pod, device) (rate(node_disk_read_bytes_total[$__rate_interval])) + ignoring(pod) group_right() (label_replace(count by(instance, pod, device) (container_fs_writes_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\", device!~\".*sda.*\"}), \"device\", \"$1\", \"device\", \"/dev/(.*)\") * 0)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}} - {{device}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Reads", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max by(persistentvolumeclaim) (kubelet_volume_stats_used_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\"} / kubelet_volume_stats_capacity_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\"}) and count by(persistentvolumeclaim) (kube_persistentvolumeclaim_labels{cluster=~\"$cluster\", namespace=~\"$namespace\",label_name=~\"(loki|enterprise-logs)-read.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{persistentvolumeclaim}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Space Utilization", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "loki_boltdb_shipper_query_readiness_duration_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "duration", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Query Readiness Duration", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Read path", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_cpu_quota{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"} / container_spec_cpu_period{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "CPU", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 9, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_memory_limit_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"} > 0)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (workingset)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (go_memstats_heap_inuse_bytes{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (go heap inuse)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Ingester", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Reads Resources", + "uid": "reads-resources", + "version": 0 + } \ No newline at end of file diff --git a/charts/loki/src/dashboards/loki-reads.json b/charts/loki/src/dashboards/loki-reads.json new file mode 100644 index 0000000..6cae30f --- /dev/null +++ b/charts/loki/src/dashboards/loki-reads.json @@ -0,0 +1,504 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + "1xx": "#EAB839", + "2xx": "#7EB26D", + "3xx": "#6ED0E0", + "4xx": "#EF843C", + "5xx": "#E24D42", + "error": "#E24D42", + "success": "#7EB26D" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{status}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "QPS", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\", cluster=~\"$cluster\"})) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ route }} 99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\", cluster=~\"$cluster\"})) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ route }} 50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "1e3 * sum(job_route:loki_request_duration_seconds_sum:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\", cluster=~\"$cluster\"}) by (route) / sum(job_route:loki_request_duration_seconds_count:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\", cluster=~\"$cluster\"}) by (route) ", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ route }} Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Read Path", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + "1xx": "#EAB839", + "2xx": "#7EB26D", + "3xx": "#6ED0E0", + "4xx": "#EF843C", + "5xx": "#E24D42", + "error": "#E24D42", + "success": "#7EB26D" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{status}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "QPS", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_boltdb_shipper_request_duration_seconds_sum{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "BoltDB Shipper", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Reads", + "uid": "reads", + "version": 0 + } \ No newline at end of file diff --git a/charts/loki/src/dashboards/loki-retention.json b/charts/loki/src/dashboards/loki-retention.json new file mode 100644 index 0000000..7fc99ec --- /dev/null +++ b/charts/loki/src/dashboards/loki-retention.json @@ -0,0 +1,1537 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_cpu_quota{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"} / container_spec_cpu_period{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "CPU", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_memory_limit_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"} > 0)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (workingset)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (go_memstats_heap_inuse_bytes{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-read\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (go heap inuse)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Resource Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "fixed" + }, + "custom": { }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "dateTimeFromNow" + } + }, + "fill": 1, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": { }, + "textMode": "auto" + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "loki_boltdb_shipper_compact_tables_operation_last_successful_run_timestamp_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\"} * 1e3", + "format": "time_series", + "instant": true, + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Last Compact and Mark Operation Success", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "stat", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "loki_boltdb_shipper_compact_tables_operation_duration_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "duration", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Compact and Mark Operations Duration", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status)(rate(loki_boltdb_shipper_compact_tables_operation_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{success}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Compact and Mark Operations Per Status", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Compact and Mark", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "count by(action)(loki_boltdb_shipper_retention_marker_table_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{action}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Processed Tables Per Action", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "count by(table,action)(loki_boltdb_shipper_retention_marker_table_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\" , action=~\"modified|deleted\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{table}}-{{action}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Modified Tables", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 9, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (table)(rate(loki_boltdb_shipper_retention_marker_count_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) >0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{table}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Marks Creation Rate Per Table", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Per Table Marker", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "format": "short", + "id": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (increase(loki_boltdb_shipper_retention_marker_count_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[24h]))", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Marked Chunks (24h)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "singlestat", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 11, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_retention_marker_table_processed_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_retention_marker_table_processed_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_boltdb_shipper_retention_marker_table_processed_duration_seconds_sum{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_retention_marker_table_processed_duration_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Mark Table Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "format": "short", + "id": 12, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (increase(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\"}[24h]))", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Delete Chunks (24h)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "singlestat", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 13, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_sum{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Delete Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Sweeper", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "time() - (loki_boltdb_shipper_retention_sweeper_marker_file_processing_current_time{cluster=~\"$cluster\", namespace=~\"$namespace\"} > 0)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "lag", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Sweeper Lag", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 15, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(loki_boltdb_shipper_retention_sweeper_marker_files_current{cluster=~\"$cluster\", namespace=~\"$namespace\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "count", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Marks Files to Process", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 16, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status)(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{status}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Delete Rate Per Status", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "datasource": "$logs", + "id": 17, + "span": 12, + "targets": [ + { + "expr": "{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-read\"}", + "refId": "A" + } + ], + "title": "Compactor Logs", + "type": "logs" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Logs", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "hide": 0, + "label": null, + "name": "logs", + "options": [ ], + "query": "loki", + "refresh": 1, + "regex": "", + "type": "datasource" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Retention", + "uid": "retention", + "version": 0 + } \ No newline at end of file diff --git a/charts/loki/src/dashboards/loki-writes-resources.json b/charts/loki/src/dashboards/loki-writes-resources.json new file mode 100644 index 0000000..1b68bd3 --- /dev/null +++ b/charts/loki/src/dashboards/loki-writes-resources.json @@ -0,0 +1,700 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (loki_ingester_memory_streams{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "In-memory streams", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_cpu_quota{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"} / container_spec_cpu_period{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "CPU", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_memory_limit_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"} > 0)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (workingset)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (go_memstats_heap_inuse_bytes{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (go heap inuse)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "gridPos": { }, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(instance, pod, device) (rate(node_disk_written_bytes_total[$__rate_interval])) + ignoring(pod) group_right() (label_replace(count by(instance, pod, device) (container_fs_writes_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\", device!~\".*sda.*\"}), \"device\", \"$1\", \"device\", \"/dev/(.*)\") * 0)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}} - {{device}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Writes", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "gridPos": { }, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(instance, pod, device) (rate(node_disk_read_bytes_total[$__rate_interval])) + ignoring(pod) group_right() (label_replace(count by(instance, pod, device) (container_fs_writes_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\", device!~\".*sda.*\"}), \"device\", \"$1\", \"device\", \"/dev/(.*)\") * 0)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}} - {{device}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Reads", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max by(persistentvolumeclaim) (kubelet_volume_stats_used_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\"} / kubelet_volume_stats_capacity_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\"}) and count by(persistentvolumeclaim) (kube_persistentvolumeclaim_labels{cluster=~\"$cluster\", namespace=~\"$namespace\",label_name=~\"(loki|enterprise-logs)-write.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{persistentvolumeclaim}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Space Utilization", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Write path", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Writes Resources", + "uid": "writes-resources", + "version": 0 + } \ No newline at end of file diff --git a/charts/loki/src/dashboards/loki-writes.json b/charts/loki/src/dashboards/loki-writes.json new file mode 100644 index 0000000..ebaf33e --- /dev/null +++ b/charts/loki/src/dashboards/loki-writes.json @@ -0,0 +1,504 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + "1xx": "#EAB839", + "2xx": "#7EB26D", + "3xx": "#6ED0E0", + "4xx": "#EF843C", + "5xx": "#E24D42", + "error": "#E24D42", + "success": "#7EB26D" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push|/httpgrpc.HTTP/Handle\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{status}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "QPS", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "1e3 * sum(job:loki_request_duration_seconds_sum:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"}) / sum(job:loki_request_duration_seconds_count:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Write Path", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + "1xx": "#EAB839", + "2xx": "#7EB26D", + "3xx": "#6ED0E0", + "4xx": "#EF843C", + "5xx": "#E24D42", + "error": "#E24D42", + "success": "#7EB26D" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{status}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "QPS", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_boltdb_shipper_request_duration_seconds_sum{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "BoltDB Shipper", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Writes", + "uid": "writes", + "version": 0 + } \ No newline at end of file diff --git a/charts/loki/src/helm-test/Dockerfile b/charts/loki/src/helm-test/Dockerfile new file mode 100644 index 0000000..c831329 --- /dev/null +++ b/charts/loki/src/helm-test/Dockerfile @@ -0,0 +1,13 @@ +ARG GO_VERSION=1.24 +FROM golang:${GO_VERSION} as build + +# build via Makefile target helm-test-image in root +# Makefile. Building from this directory will not be +# able to access source needed in rest of repo. +COPY . /src/loki +WORKDIR /src/loki +RUN make clean && make BUILD_IN_CONTAINER=false helm-test + +FROM gcr.io/distroless/static:debug +COPY --from=build /src/loki/production/helm/loki/src/helm-test/helm-test /usr/bin/helm-test +ENTRYPOINT [ "/usr/bin/helm-test" ] diff --git a/charts/loki/src/helm-test/README.md b/charts/loki/src/helm-test/README.md new file mode 100644 index 0000000..68c9bfd --- /dev/null +++ b/charts/loki/src/helm-test/README.md @@ -0,0 +1,7 @@ +# Loki Helm Test + +This folder contains a collection of go tests that test if a Loki canary is running correctly. It's primary use it to test that the helm chart is working correctly by using metrics from the Loki canary. In the helm chart, the template for this test is only available if you are running both the Loki canary and have self monitoring enabled (as the Loki canary's logs need to be in Loki for it to work). However, the tests in this folder can be run against any running Loki canary using `go test`. + +## Instructions + +Run `go test .` from this directory, or use the Docker image published at `grafana/loki-helm-test`. diff --git a/charts/loki/src/helm-test/canary_test.go b/charts/loki/src/helm-test/canary_test.go new file mode 100644 index 0000000..002cae4 --- /dev/null +++ b/charts/loki/src/helm-test/canary_test.go @@ -0,0 +1,178 @@ +//go:build helm_test +// +build helm_test + +package test + +import ( + "context" + "errors" + "fmt" + "io" + "net/http" + "os" + "testing" + "time" + + "github.com/prometheus/client_golang/api" + v1 "github.com/prometheus/client_golang/api/prometheus/v1" + promConfig "github.com/prometheus/common/config" + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/model/labels" + "github.com/prometheus/prometheus/model/textparse" + "github.com/stretchr/testify/require" +) + +type testResultFunc func(t *testing.T, ctx context.Context, metric string, test func(model.SampleValue) bool, msg string) error + +func TestCanary(t *testing.T) { + + var testResult testResultFunc + + // Default to directly querying a canary and looking for specific metrics. + testResult = testResultCanary + totalEntries := "loki_canary_entries_total" + totalEntriesMissing := "loki_canary_missing_entries_total" + + // For backwards compatibility and also for anyone who wants to validate with prometheus instead of querying + // a canary directly, if the CANARY_PROMETHEUS_ADDRESS is specified we will use prometheus to validate. + address := os.Getenv("CANARY_PROMETHEUS_ADDRESS") + if address != "" { + testResult = testResultPrometheus + // Use the sum function to aggregate the results from multiple canaries. + totalEntries = "sum(loki_canary_entries_total)" + totalEntriesMissing = "sum(loki_canary_missing_entries_total)" + } + + timeout := getEnv("CANARY_TEST_TIMEOUT", "1m") + timeoutDuration, err := time.ParseDuration(timeout) + require.NoError(t, err, "Failed to parse timeout. Please set CANARY_TEST_TIMEOUT to a valid duration.") + + ctx, cancel := context.WithTimeout(context.Background(), timeoutDuration) + + t.Cleanup(func() { + cancel() + }) + + t.Run("Canary should have entries", func(t *testing.T) { + eventually(t, func() error { + return testResult(t, ctx, totalEntries, func(v model.SampleValue) bool { + return v > 0 + }, fmt.Sprintf("Expected %s to be greater than 0", totalEntries)) + }, timeoutDuration, "Expected Loki Canary to have entries") + }) + + t.Run("Canary should not have missed any entries", func(t *testing.T) { + eventually(t, func() error { + return testResult(t, ctx, totalEntriesMissing, func(v model.SampleValue) bool { + return v == 0 + }, fmt.Sprintf("Expected %s to equal 0", totalEntriesMissing)) + }, timeoutDuration, "Expected Loki Canary to not have any missing entries") + }) +} + +func getEnv(key, fallback string) string { + if value, ok := os.LookupEnv(key); ok { + return value + } + return fallback +} + +func testResultPrometheus(t *testing.T, ctx context.Context, query string, test func(model.SampleValue) bool, msg string) error { + // TODO (ewelch): if we did a lot of these, we'd want to reuse the client but right now we only run a couple tests + client := newClient(t) + result, _, err := client.Query(ctx, query, time.Now()) + if err != nil { + return err + } + if v, ok := result.(model.Vector); ok { + for _, s := range v { + t.Logf("%s => %v\n", query, s.Value) + if !test(s.Value) { + return errors.New(msg) + } + } + return nil + } + + return fmt.Errorf("unexpected Prometheus result type: %v ", result.Type()) +} + +func newClient(t *testing.T) v1.API { + address := os.Getenv("CANARY_PROMETHEUS_ADDRESS") + require.NotEmpty(t, address, "CANARY_PROMETHEUS_ADDRESS must be set to a valid prometheus address") + + client, err := api.NewClient(api.Config{ + Address: address, + }) + require.NoError(t, err, "Failed to create Loki Canary client") + + return v1.NewAPI(client) +} + +func testResultCanary(t *testing.T, ctx context.Context, metric string, test func(model.SampleValue) bool, msg string) error { + address := os.Getenv("CANARY_SERVICE_ADDRESS") + require.NotEmpty(t, address, "CANARY_SERVICE_ADDRESS must be set to a valid kubernetes service for the Loki canaries") + + // TODO (ewelch): if we did a lot of these, we'd want to reuse the client but right now we only run a couple tests + client, err := promConfig.NewClientFromConfig(promConfig.HTTPClientConfig{}, "canary-test") + require.NoError(t, err, "Failed to create Prometheus client") + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, address, nil) + require.NoError(t, err, "Failed to create request") + + rsp, err := client.Do(req) + if rsp != nil { + defer rsp.Body.Close() + } + require.NoError(t, err, "Failed to scrape metrics") + + body, err := io.ReadAll(rsp.Body) + require.NoError(t, err, "Failed to read response body") + + p, err := textparse.New(body, rsp.Header.Get("Content-Type"), true, nil) + require.NoError(t, err, "Failed to create Prometheus parser") + + for { + e, err := p.Next() + if err == io.EOF { + return errors.New("metric not found") + } + + if e != textparse.EntrySeries { + continue + } + + l := labels.Labels{} + p.Metric(&l) + + // Currently we aren't validating any labels, just the metric name, however this could be extended to do so. + name := l.Get(model.MetricNameLabel) + if name != metric { + continue + } + + _, _, val := p.Series() + t.Logf("%s => %v\n", metric, val) + + // Note: SampleValue has functions for comparing the equality of two floats which is + // why we convert this back to a SampleValue here for easier use intests. + if !test(model.SampleValue(val)) { + return errors.New(msg) + } + + // Returning here will only validate that one series was found matching the label name that met the condition + // it could be possible since we don't validate the rest of the labels that there is mulitple series + // but currently this meets the spirit of the test. + return nil + } +} + +func eventually(t *testing.T, test func() error, timeoutDuration time.Duration, msg string) { + require.Eventually(t, func() bool { + queryError := test() + if queryError != nil { + t.Logf("Query failed\n%+v\n", queryError) + } + return queryError == nil + }, timeoutDuration, 1*time.Second, msg) +} diff --git a/charts/loki/src/helm-test/default.nix b/charts/loki/src/helm-test/default.nix new file mode 100644 index 0000000..a129b23 --- /dev/null +++ b/charts/loki/src/helm-test/default.nix @@ -0,0 +1,27 @@ +{ pkgs, lib, buildGoModule, dockerTools, rev }: +rec { + loki-helm-test = buildGoModule rec { + pname = "loki-helm-test"; + version = "0.1.0"; + + src = ./../../../../..; + vendorHash = null; + + buildPhase = '' + runHook preBuild + go test --tags=helm_test -c -o $out/bin/helm-test ./production/helm/loki/src/helm-test + runHook postBuild + ''; + + doCheck = false; + }; + + # by default, uses the nix hash as the tag, which can be retrieved with: + # basename "$(readlink result)" | cut -d - -f 1 + loki-helm-test-docker = dockerTools.buildImage { + name = "grafana/loki-helm-test"; + config = { + Entrypoint = [ "${loki-helm-test}/bin/helm-test" ]; + }; + }; +} diff --git a/charts/loki/src/rules.yaml.tpl b/charts/loki/src/rules.yaml.tpl new file mode 100644 index 0000000..840401d --- /dev/null +++ b/charts/loki/src/rules.yaml.tpl @@ -0,0 +1,86 @@ +--- +groups: + - name: "loki_rules" + rules: + - expr: histogram_quantile(0.99, sum(rate(loki_request_duration_seconds_bucket[1m])) + by (le, job)) + record: job:loki_request_duration_seconds:99quantile + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: histogram_quantile(0.50, sum(rate(loki_request_duration_seconds_bucket[1m])) + by (le, job)) + record: job:loki_request_duration_seconds:50quantile + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (job) / sum(rate(loki_request_duration_seconds_count[1m])) + by (job) + record: job:loki_request_duration_seconds:avg + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job) + record: job:loki_request_duration_seconds_bucket:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (job) + record: job:loki_request_duration_seconds_sum:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_count[1m])) by (job) + record: job:loki_request_duration_seconds_count:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: histogram_quantile(0.99, sum(rate(loki_request_duration_seconds_bucket[1m])) + by (le, job, route)) + record: job_route:loki_request_duration_seconds:99quantile + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: histogram_quantile(0.50, sum(rate(loki_request_duration_seconds_bucket[1m])) + by (le, job, route)) + record: job_route:loki_request_duration_seconds:50quantile + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (job, route) / sum(rate(loki_request_duration_seconds_count[1m])) + by (job, route) + record: job_route:loki_request_duration_seconds:avg + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job, route) + record: job_route:loki_request_duration_seconds_bucket:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (job, route) + record: job_route:loki_request_duration_seconds_sum:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_count[1m])) by (job, route) + record: job_route:loki_request_duration_seconds_count:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: histogram_quantile(0.99, sum(rate(loki_request_duration_seconds_bucket[1m])) + by (le, namespace, job, route)) + record: namespace_job_route:loki_request_duration_seconds:99quantile + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: histogram_quantile(0.50, sum(rate(loki_request_duration_seconds_bucket[1m])) + by (le, namespace, job, route)) + record: namespace_job_route:loki_request_duration_seconds:50quantile + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (namespace, job, route) + / sum(rate(loki_request_duration_seconds_count[1m])) by (namespace, job, route) + record: namespace_job_route:loki_request_duration_seconds:avg + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, namespace, job, + route) + record: namespace_job_route:loki_request_duration_seconds_bucket:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (namespace, job, route) + record: namespace_job_route:loki_request_duration_seconds_sum:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_count[1m])) by (namespace, job, route) + record: namespace_job_route:loki_request_duration_seconds_count:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" diff --git a/charts/loki/templates/NOTES.txt b/charts/loki/templates/NOTES.txt new file mode 100644 index 0000000..336a354 --- /dev/null +++ b/charts/loki/templates/NOTES.txt @@ -0,0 +1,184 @@ +*********************************************************************** + Welcome to Grafana Loki + Chart version: {{ .Chart.Version }} + Chart Name: {{ .Chart.Name }} + Loki version: {{ .Chart.AppVersion }} +*********************************************************************** + +** Please be patient while the chart is being deployed ** + +Tip: + + Watch the deployment status using the command: kubectl get pods -w --namespace {{ $.Release.Namespace }} + +If pods are taking too long to schedule make sure pod affinity can be fulfilled in the current cluster. + +*********************************************************************** +Installed components: +*********************************************************************** + +{{- if .Values.monitoring.selfMonitoring.enabled }} +* grafana-agent-operator +{{- end }} +{{- if eq (include "loki.deployment.isSingleBinary" .) "true" }} +* loki +{{- else -}} +{{- if .Values.gateway.enabled }} +* gateway +{{- end }} +{{- if .Values.minio.enabled }} +* minio +{{- end }} +{{- if eq (include "loki.deployment.isScalable" .) "true" }} +* read +* write +{{- if not .Values.read.legacyReadTarget }} +* backend +{{- end }} +{{- else }} +* compactor +* index gateway +* query scheduler +* ruler +* distributor +* ingester +* querier +* query frontend +{{- end }} +{{- end }} + + +{{- if eq (include "loki.deployment.isSingleBinary" .) "true" }} + +Loki has been deployed as a single binary. +This means a single pod is handling reads and writes. You can scale that pod vertically by adding more CPU and memory resources. + +{{- end }} + + +*********************************************************************** +Sending logs to Loki +*********************************************************************** + +{{- if .Values.gateway.enabled }} + +Loki has been configured with a gateway (nginx) to support reads and writes from a single component. + +{{- end }} + +You can send logs from inside the cluster using the cluster DNS: + +{{- if .Values.gateway.enabled }} + +http://{{ include "loki.gatewayFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}/loki/api/v1/push + +{{- else }} +{{- if eq (include "loki.deployment.isSingleBinary" .) "true" }} + +http://{{ include "loki.singleBinaryFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:{{ .Values.loki.server.http_listen_port }}/loki/api/v1/push + +{{- end}} +{{- if eq (include "loki.deployment.isScalable" .) "true" }} + +http://{{ include "loki.writeFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:{{ .Values.loki.server.http_listen_port }}/loki/api/v1/push + +{{- end }} +{{- if eq (include "loki.deployment.isDistributed" .) "true" }} + +http://{{ include "loki.distributorFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:3100/loki/api/v1/push + +{{- end }} +{{- end }} + +You can test to send data from outside the cluster by port-forwarding the gateway to your local machine: +{{- if .Values.gateway.enabled }} + + kubectl port-forward --namespace {{ $.Release.Namespace }} svc/{{ include "loki.gatewayFullname" . }} 3100:{{ .Values.gateway.service.port }} & + +{{- else }} +{{- if eq (include "loki.deployment.isSingleBinary" .) "true" }} + + kubectl port-forward --namespace {{ $.Release.Namespace }} svc/{{ include "loki.singleBinaryFullname" . }} 3100:{{ .Values.loki.server.http_listen_port }} & + +{{- end}} +{{- if eq (include "loki.deployment.isScalable" .) "true" }} + + kubectl port-forward --namespace {{ $.Release.Namespace }} svc/{{ include "loki.writeFullname" . }} 3100:{{ .Values.loki.server.http_listen_port }} & + +{{- end }} +{{- if eq (include "loki.deployment.isDistributed" .) "true" }} + + kubectl port-forward --namespace {{ $.Release.Namespace }} svc/{{ include "loki.distributorFullname" . }} 3100:3100 & + +{{- end }} +{{- end }} + +And then using http://127.0.0.1:3100/loki/api/v1/push URL as shown below: + +``` +curl -H "Content-Type: application/json" -XPOST -s "http://127.0.0.1:3100/loki/api/v1/push" \ +--data-raw "{\"streams\": [{\"stream\": {\"job\": \"test\"}, \"values\": [[\"$(date +%s)000000000\", \"fizzbuzz\"]]}]}" +{{- if .Values.loki.auth_enabled }} \ +-H X-Scope-OrgId:foo +{{- end}} +``` + +Then verify that Loki did receive the data using the following command: + +``` +curl "http://127.0.0.1:3100/loki/api/v1/query_range" --data-urlencode 'query={job="test"}' {{- if .Values.loki.auth_enabled }} -H X-Scope-OrgId:foo {{- end}} | jq .data.result +``` + +*********************************************************************** +Connecting Grafana to Loki +*********************************************************************** + +If Grafana operates within the cluster, you'll set up a new Loki datasource by utilizing the following URL: + +{{- if .Values.gateway.enabled }} + +http://{{ include "loki.gatewayFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}/ + +{{- else }} +{{- if eq (include "loki.deployment.isSingleBinary" .) "true" }} + +http://{{ include "loki.singleBinaryFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:{{ .Values.loki.server.http_listen_port }}/ + +{{- end}} +{{- if eq (include "loki.deployment.isScalable" .) "true" }} + +http://{{ include "loki.readFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:{{ .Values.loki.server.http_listen_port }}/ + +{{- end }} +{{- if eq (include "loki.deployment.isDistributed" .) "true" }} + +http://{{ include "loki.queryFrontendFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:3100/ + +{{- end }} +{{- end }} + + + +{{- if .Values.loki.auth_enabled }} + +*********************************************************************** +Multi-tenancy +*********************************************************************** + +Loki is configured with auth enabled (multi-tenancy) and expects tenant headers (`X-Scope-OrgID`) to be set for all API calls. + +You must configure Grafana's Loki datasource using the `HTTP Headers` section with the `X-Scope-OrgID` to target a specific tenant. +For each tenant, you can create a different datasource. + +The agent of your choice must also be configured to propagate this header. +For example, when using Promtail you can use the `tenant` stage. https://grafana.com/docs/loki/latest/send-data/promtail/stages/tenant/ + +When not provided with the `X-Scope-OrgID` while auth is enabled, Loki will reject reads and writes with a 404 status code `no org id`. + +You can also use a reverse proxy, to automatically add the `X-Scope-OrgID` header as suggested by https://grafana.com/docs/loki/latest/operations/authentication/ + +For more information, read our documentation about multi-tenancy: https://grafana.com/docs/loki/latest/operations/multi-tenancy/ + +> When using curl you can pass `X-Scope-OrgId` header using `-H X-Scope-OrgId:foo` option, where foo can be replaced with the tenant of your choice. + +{{- end }} diff --git a/charts/loki/templates/_helpers.tpl b/charts/loki/templates/_helpers.tpl new file mode 100644 index 0000000..083d035 --- /dev/null +++ b/charts/loki/templates/_helpers.tpl @@ -0,0 +1,1197 @@ +{{/* +Enforce valid label value. +See https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set +*/}} +{{- define "loki.validLabelValue" -}} +{{- (regexReplaceAllLiteral "[^a-zA-Z0-9._-]" . "-") | trunc 63 | trimSuffix "-" | trimSuffix "_" | trimSuffix "." }} +{{- end }} + +{{/* +Expand the name of the chart. +*/}} +{{- define "loki.name" -}} +{{- $default := ternary "enterprise-logs" "loki" .Values.enterprise.enabled }} +{{- coalesce .Values.nameOverride $default | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +singleBinary fullname +*/}} +{{- define "loki.singleBinaryFullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Resource name template +Params: + ctx = . context + component = component name (optional) + rolloutZoneName = rollout zone name (optional) +*/}} +{{- define "loki.resourceName" -}} +{{- $resourceName := include "loki.fullname" .ctx -}} +{{- if .component -}}{{- $resourceName = printf "%s-%s" $resourceName .component -}}{{- end -}} +{{- if and (not .component) .rolloutZoneName -}}{{- printf "Component name cannot be empty if rolloutZoneName (%s) is set" .rolloutZoneName | fail -}}{{- end -}} +{{- if .rolloutZoneName -}}{{- $resourceName = printf "%s-%s" $resourceName .rolloutZoneName -}}{{- end -}} +{{- if gt (len $resourceName) 253 -}}{{- printf "Resource name (%s) exceeds kubernetes limit of 253 character. To fix: shorten release name if this will be a fresh install or shorten zone names (e.g. \"a\" instead of \"zone-a\") if using zone-awareness." $resourceName | fail -}}{{- end -}} +{{- $resourceName -}} +{{- end -}} + +{{/* +Return if deployment mode is simple scalable +*/}} +{{- define "loki.deployment.isScalable" -}} + {{- and (eq (include "loki.isUsingObjectStorage" . ) "true") (or (eq .Values.deploymentMode "SingleBinary<->SimpleScalable") (eq .Values.deploymentMode "SimpleScalable") (eq .Values.deploymentMode "SimpleScalable<->Distributed")) }} +{{- end -}} + +{{/* +Return if deployment mode is single binary +*/}} +{{- define "loki.deployment.isSingleBinary" -}} + {{- or (eq .Values.deploymentMode "SingleBinary") (eq .Values.deploymentMode "SingleBinary<->SimpleScalable") }} +{{- end -}} + +{{/* +Return if deployment mode is distributed +*/}} +{{- define "loki.deployment.isDistributed" -}} + {{- and (eq (include "loki.isUsingObjectStorage" . ) "true") (or (eq .Values.deploymentMode "Distributed") (eq .Values.deploymentMode "SimpleScalable<->Distributed")) }} +{{- end -}} + + +{{/* +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 "loki.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := include "loki.name" . }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Cluster label for rules and alerts. +*/}} +{{- define "loki.clusterLabel" -}} +{{- if .Values.clusterLabelOverride }} +{{- .Values.clusterLabelOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := include "loki.name" . }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} + +{{/* Create a default storage config that uses filesystem storage +This is required for CI, but Loki will not be queryable with this default +applied, thus it is encouraged that users override this. +*/}} +{{- define "loki.storageConfig" -}} +{{- if .Values.loki.storageConfig -}} +{{- .Values.loki.storageConfig | toYaml | nindent 4 -}} +{{- else }} +{{- .Values.loki.defaultStorageConfig | toYaml | nindent 4 }} +{{- end}} +{{- end}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "loki.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "loki.labels" -}} +helm.sh/chart: {{ include "loki.chart" . }} +{{ include "loki.selectorLabels" . }} +{{- if or (.Chart.AppVersion) (.Values.loki.image.tag) }} +app.kubernetes.io/version: {{ include "loki.validLabelValue" (.Values.loki.image.tag | default .Chart.AppVersion) | quote }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "loki.selectorLabels" -}} +app.kubernetes.io/name: {{ include "loki.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "loki.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "loki.name" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Base template for building docker image reference +*/}} +{{- define "loki.baseImage" }} +{{- $registry := .global.registry | default .service.registry | default "" -}} +{{- $repository := .service.repository | default "" -}} +{{- $ref := ternary (printf ":%s" (.service.tag | default .defaultVersion | toString)) (printf "@%s" .service.digest) (empty .service.digest) -}} +{{- if and $registry $repository -}} + {{- printf "%s/%s%s" $registry $repository $ref -}} +{{- else -}} + {{- printf "%s%s%s" $registry $repository $ref -}} +{{- end -}} +{{- end -}} + +{{/* +Docker image name for Loki +*/}} +{{- define "loki.lokiImage" -}} +{{- $dict := dict "service" .Values.loki.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}} +{{- include "loki.baseImage" $dict -}} +{{- end -}} + +{{/* +Docker image name for enterprise logs +*/}} +{{- define "loki.enterpriseImage" -}} +{{- $dict := dict "service" .Values.enterprise.image "global" .Values.global.image "defaultVersion" .Values.enterprise.version -}} +{{- include "loki.baseImage" $dict -}} +{{- end -}} + +{{/* +Docker image name +*/}} +{{- define "loki.image" -}} +{{- if .Values.enterprise.enabled -}}{{- include "loki.enterpriseImage" . -}}{{- else -}}{{- include "loki.lokiImage" . -}}{{- end -}} +{{- end -}} + +{{/* +Docker image name for kubectl container +*/}} +{{- define "loki.kubectlImage" -}} +{{- $dict := dict "service" .Values.kubectlImage "global" .Values.global.image "defaultVersion" "latest" -}} +{{- include "loki.baseImage" $dict -}} +{{- end -}} + +{{/* +Generated storage config for loki common config +*/}} +{{- define "loki.commonStorageConfig" -}} +{{- if .Values.loki.storage.use_thanos_objstore -}} +object_store: + {{- include "loki.thanosStorageConfig" (dict "ctx" . "bucketName" .Values.loki.storage.bucketNames.chunks) | nindent 2 }} +{{- else }} +{{- if .Values.minio.enabled -}} +s3: + endpoint: {{ include "loki.minio" $ }} + bucketnames: chunks + secret_access_key: {{ $.Values.minio.rootPassword }} + access_key_id: {{ $.Values.minio.rootUser }} + s3forcepathstyle: true + insecure: true +{{- else if eq .Values.loki.storage.type "s3" -}} +{{- with .Values.loki.storage.s3 }} +s3: + {{- with .s3 }} + s3: {{ . }} + {{- end }} + {{- with .endpoint }} + endpoint: {{ . }} + {{- end }} + {{- with .region }} + region: {{ . }} + {{- end}} + bucketnames: {{ $.Values.loki.storage.bucketNames.chunks }} + {{- with .secretAccessKey }} + secret_access_key: {{ . }} + {{- end }} + {{- with .accessKeyId }} + access_key_id: {{ . }} + {{- end }} + {{- with .signatureVersion }} + signature_version: {{ . }} + {{- end }} + s3forcepathstyle: {{ .s3ForcePathStyle }} + insecure: {{ .insecure }} + {{- with .disable_dualstack }} + disable_dualstack: {{ . }} + {{- end }} + {{- with .http_config}} + http_config: +{{ toYaml . | indent 4 }} + {{- end }} + {{- with .backoff_config}} + backoff_config: +{{ toYaml . | indent 4 }} + {{- end }} + {{- with .sse }} + sse: +{{ toYaml . | indent 4 }} + {{- end }} +{{- end -}} + +{{- else if eq .Values.loki.storage.type "gcs" -}} +{{- with .Values.loki.storage.gcs }} +gcs: + bucket_name: {{ $.Values.loki.storage.bucketNames.chunks }} + chunk_buffer_size: {{ .chunkBufferSize }} + request_timeout: {{ .requestTimeout }} + enable_http2: {{ .enableHttp2 }} +{{- end -}} +{{- else if eq .Values.loki.storage.type "azure" -}} +{{- with .Values.loki.storage.azure }} +azure: + account_name: {{ .accountName }} + {{- with .accountKey }} + account_key: {{ . }} + {{- end }} + {{- with .connectionString }} + connection_string: {{ . }} + {{- end }} + container_name: {{ $.Values.loki.storage.bucketNames.chunks }} + use_managed_identity: {{ .useManagedIdentity }} + use_federated_token: {{ .useFederatedToken }} + {{- with .userAssignedId }} + user_assigned_id: {{ . }} + {{- end }} + {{- with .requestTimeout }} + request_timeout: {{ . }} + {{- end }} + {{- with .endpointSuffix }} + endpoint_suffix: {{ . }} + {{- end }} + {{- with .chunkDelimiter }} + chunk_delimiter: {{ . }} + {{- end }} +{{- end -}} +{{- else if eq .Values.loki.storage.type "alibabacloud" -}} +{{- with .Values.loki.storage.alibabacloud }} +alibabacloud: + bucket: {{ $.Values.loki.storage.bucketNames.chunks }} + endpoint: {{ .endpoint }} + access_key_id: {{ .accessKeyId }} + secret_access_key: {{ .secretAccessKey }} +{{- end -}} +{{- else if eq .Values.loki.storage.type "swift" -}} +{{- with .Values.loki.storage.swift }} +swift: +{{ toYaml . | indent 2 }} +{{- end -}} +{{- else -}} +{{- with .Values.loki.storage.filesystem }} +filesystem: + chunks_directory: {{ .chunks_directory }} + rules_directory: {{ .rules_directory }} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Storage config for ruler +*/}} +{{- define "loki.rulerStorageConfig" -}} +{{- if .Values.minio.enabled -}} +type: "s3" +s3: + bucketnames: ruler +{{- else if eq .Values.loki.storage.type "s3" -}} +{{- with .Values.loki.storage.s3 }} +type: "s3" +s3: + {{- with .s3 }} + s3: {{ . }} + {{- end }} + {{- with .endpoint }} + endpoint: {{ . }} + {{- end }} + {{- with .region }} + region: {{ . }} + {{- end}} + bucketnames: {{ $.Values.loki.storage.bucketNames.ruler }} + {{- with .secretAccessKey }} + secret_access_key: {{ . }} + {{- end }} + {{- with .accessKeyId }} + access_key_id: {{ . }} + {{- end }} + s3forcepathstyle: {{ .s3ForcePathStyle }} + insecure: {{ .insecure }} + {{- with .http_config }} + http_config: {{ toYaml . | nindent 6 }} + {{- end }} +{{- end -}} +{{- else if eq .Values.loki.storage.type "gcs" -}} +{{- with .Values.loki.storage.gcs }} +type: "gcs" +gcs: + bucket_name: {{ $.Values.loki.storage.bucketNames.ruler }} + chunk_buffer_size: {{ .chunkBufferSize }} + request_timeout: {{ .requestTimeout }} + enable_http2: {{ .enableHttp2 }} +{{- end -}} +{{- else if eq .Values.loki.storage.type "azure" -}} +{{- with .Values.loki.storage.azure }} +type: "azure" +azure: + account_name: {{ .accountName }} + {{- with .accountKey }} + account_key: {{ . }} + {{- end }} + {{- with .connectionString }} + connection_string: {{ . }} + {{- end }} + container_name: {{ $.Values.loki.storage.bucketNames.ruler }} + use_managed_identity: {{ .useManagedIdentity }} + use_federated_token: {{ .useFederatedToken }} + {{- with .userAssignedId }} + user_assigned_id: {{ . }} + {{- end }} + {{- with .requestTimeout }} + request_timeout: {{ . }} + {{- end }} + {{- with .endpointSuffix }} + endpoint_suffix: {{ . }} + {{- end }} +{{- end -}} +{{- else if eq .Values.loki.storage.type "swift" -}} +{{- with .Values.loki.storage.swift }} +swift: + {{- with .auth_version }} + auth_version: {{ . }} + {{- end }} + auth_url: {{ .auth_url }} + {{- with .internal }} + internal: {{ . }} + {{- end }} + username: {{ .username }} + user_domain_name: {{ .user_domain_name }} + {{- with .user_domain_id }} + user_domain_id: {{ . }} + {{- end }} + {{- with .user_id }} + user_id: {{ . }} + {{- end }} + password: {{ .password }} + {{- with .domain_id }} + domain_id: {{ . }} + {{- end }} + domain_name: {{ .domain_name }} + project_id: {{ .project_id }} + project_name: {{ .project_name }} + project_domain_id: {{ .project_domain_id }} + project_domain_name: {{ .project_domain_name }} + region_name: {{ .region_name }} + container_name: {{ .container_name }} + max_retries: {{ .max_retries | default 3 }} + connect_timeout: {{ .connect_timeout | default "10s" }} + request_timeout: {{ .request_timeout | default "5s" }} +{{- end -}} +{{- else }} +type: "local" +{{- end -}} +{{- end -}} + +{{/* Loki ruler config */}} +{{- define "loki.rulerConfig" }} +ruler: + storage: + {{- include "loki.rulerStorageConfig" . | nindent 4}} +{{- if (not (empty .Values.loki.rulerConfig)) }} +{{- toYaml .Values.loki.rulerConfig | nindent 2}} +{{- end }} +{{- end }} + +{{/* Ruler Thanos Storage Config */}} +{{- define "loki.rulerThanosStorageConfig" -}} +{{- if and .Values.loki.storage.use_thanos_objstore .Values.ruler.enabled}} + backend: {{ .Values.loki.storage.object_store.type }} + {{- include "loki.thanosStorageConfig" (dict "ctx" . "bucketName" .Values.loki.storage.bucketNames.ruler) | nindent 2 }} +{{- end }} +{{- end }} + +{{/* Enterprise Logs Admin API storage config */}} +{{- define "enterprise-logs.adminAPIStorageConfig" }} +storage: + {{- if .Values.loki.storage.use_thanos_objstore }} + backend: {{ .Values.loki.storage.object_store.type }} + {{- include "loki.thanosStorageConfig" (dict "ctx" . "bucketName" .Values.loki.storage.bucketNames.admin) | nindent 2 }} + {{- else if .Values.minio.enabled }} + backend: "s3" + s3: + bucket_name: admin + {{- else if eq .Values.loki.storage.type "s3" -}} + {{- with .Values.loki.storage.s3 }} + backend: "s3" + s3: + bucket_name: {{ $.Values.loki.storage.bucketNames.admin }} + {{- end -}} + {{- else if eq .Values.loki.storage.type "gcs" -}} + {{- with .Values.loki.storage.gcs }} + backend: "gcs" + gcs: + bucket_name: {{ $.Values.loki.storage.bucketNames.admin }} + {{- end -}} + {{- else if eq .Values.loki.storage.type "azure" -}} + {{- with .Values.loki.storage.azure }} + backend: "azure" + azure: + account_name: {{ .accountName }} + {{- with .accountKey }} + account_key: {{ . }} + {{- end }} + {{- with .connectionString }} + connection_string: {{ . }} + {{- end }} + container_name: {{ $.Values.loki.storage.bucketNames.admin }} + {{- with .endpointSuffix }} + endpoint_suffix: {{ . }} + {{- end }} + {{- end -}} + {{- else if eq .Values.loki.storage.type "swift" -}} + {{- with .Values.loki.storage.swift }} + backend: "swift" + swift: + {{- with .auth_version }} + auth_version: {{ . }} + {{- end }} + auth_url: {{ .auth_url }} + {{- with .internal }} + internal: {{ . }} + {{- end }} + username: {{ .username }} + user_domain_name: {{ .user_domain_name }} + {{- with .user_domain_id }} + user_domain_id: {{ . }} + {{- end }} + {{- with .user_id }} + user_id: {{ . }} + {{- end }} + password: {{ .password }} + {{- with .domain_id }} + domain_id: {{ . }} + {{- end }} + domain_name: {{ .domain_name }} + project_id: {{ .project_id }} + project_name: {{ .project_name }} + project_domain_id: {{ .project_domain_id }} + project_domain_name: {{ .project_domain_name }} + region_name: {{ .region_name }} + container_name: {{ .container_name }} + max_retries: {{ .max_retries | default 3 }} + connect_timeout: {{ .connect_timeout | default "10s" }} + request_timeout: {{ .request_timeout | default "5s" }} + {{- end -}} + {{- else }} + backend: "filesystem" + filesystem: + dir: {{ .Values.loki.storage.filesystem.admin_api_directory }} + {{- end -}} +{{- end }} + +{{/* +Calculate the config from structured and unstructured text input +*/}} +{{- define "loki.calculatedConfig" -}} +{{ tpl (mergeOverwrite (tpl .Values.loki.config . | fromYaml) .Values.loki.structuredConfig | toYaml) . }} +{{- end }} + +{{/* +The volume to mount for loki configuration +*/}} +{{- define "loki.configVolume" -}} +{{- if eq .Values.loki.configStorageType "Secret" -}} +secret: + secretName: {{ tpl .Values.loki.configObjectName . }} +{{- else -}} +configMap: + name: {{ tpl .Values.loki.configObjectName . }} + items: + - key: "config.yaml" + path: "config.yaml" +{{- end -}} +{{- end -}} + +{{/* +Memcached Docker image +*/}} +{{- define "loki.memcachedImage" -}} +{{- $dict := dict "service" .Values.memcached.image "global" .Values.global.image -}} +{{- include "loki.image" $dict -}} +{{- end }} + +{{/* +Memcached Exporter Docker image +*/}} +{{- define "loki.memcachedExporterImage" -}} +{{- $dict := dict "service" .Values.memcachedExporter.image "global" .Values.global.image -}} +{{- include "loki.image" $dict -}} +{{- end }} + +{{/* Allow KubeVersion to be overridden. */}} +{{- define "loki.kubeVersion" -}} + {{- default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "loki.ingress.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19-0" (include "loki.kubeVersion" .)) -}} + {{- print "networking.k8s.io/v1" -}} + {{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}} + {{- print "networking.k8s.io/v1beta1" -}} + {{- else -}} + {{- print "extensions/v1beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return if ingress is stable. +*/}} +{{- define "loki.ingress.isStable" -}} + {{- eq (include "loki.ingress.apiVersion" .) "networking.k8s.io/v1" -}} +{{- end -}} + +{{/* +Return if ingress supports ingressClassName. +*/}} +{{- define "loki.ingress.supportsIngressClassName" -}} + {{- or (eq (include "loki.ingress.isStable" .) "true") (and (eq (include "loki.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" (include "loki.kubeVersion" .))) -}} +{{- end -}} + +{{/* +Return if ingress supports pathType. +*/}} +{{- define "loki.ingress.supportsPathType" -}} + {{- or (eq (include "loki.ingress.isStable" .) "true") (and (eq (include "loki.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" (include "loki.kubeVersion" .))) -}} +{{- end -}} + +{{/* +Generate list of ingress service paths based on deployment type +*/}} +{{- define "loki.ingress.servicePaths" -}} +{{- if (eq (include "loki.deployment.isSingleBinary" .) "true") -}} +{{- include "loki.ingress.singleBinaryServicePaths" . }} +{{- else if (eq (include "loki.deployment.isDistributed" .) "true") -}} +{{- include "loki.ingress.distributedServicePaths" . }} +{{- else if and (eq (include "loki.deployment.isScalable" .) "true") (not .Values.read.legacyReadTarget ) -}} +{{- include "loki.ingress.scalableServicePaths" . }} +{{- else -}} +{{- include "loki.ingress.legacyScalableServicePaths" . }} +{{- end -}} +{{- end -}} + +{{/* +Ingress service paths for distributed deployment +*/}} +{{- define "loki.ingress.distributedServicePaths" -}} +{{- $distributorServiceName := include "loki.distributorFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $distributorServiceName "paths" .Values.ingress.paths.distributor )}} +{{- $queryFrontendServiceName := include "loki.queryFrontendFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $queryFrontendServiceName "paths" .Values.ingress.paths.queryFrontend )}} +{{- $rulerServiceName := include "loki.rulerFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $rulerServiceName "paths" .Values.ingress.paths.ruler)}} +{{- end -}} + +{{/* +Ingress service paths for legacy simple scalable deployment when backend components were part of read component. +*/}} +{{- define "loki.ingress.scalableServicePaths" -}} +{{- $readServiceName := include "loki.readFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $readServiceName "paths" .Values.ingress.paths.queryFrontend )}} +{{- $writeServiceName := include "loki.writeFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $writeServiceName "paths" .Values.ingress.paths.distributor )}} +{{- $backendServiceName := include "loki.backendFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $backendServiceName "paths" .Values.ingress.paths.ruler )}} +{{- end -}} + +{{/* +Ingress service paths for legacy simple scalable deployment +*/}} +{{- define "loki.ingress.legacyScalableServicePaths" -}} +{{- $readServiceName := include "loki.readFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $readServiceName "paths" .Values.ingress.paths.queryFrontend )}} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $readServiceName "paths" .Values.ingress.paths.ruler )}} +{{- $writeServiceName := include "loki.writeFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $writeServiceName "paths" .Values.ingress.paths.distributor )}} +{{- end -}} + +{{/* +Ingress service paths for single binary deployment +*/}} +{{- define "loki.ingress.singleBinaryServicePaths" -}} +{{- $serviceName := include "loki.singleBinaryFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $serviceName "paths" .Values.ingress.paths.distributor )}} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $serviceName "paths" .Values.ingress.paths.queryFrontend )}} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $serviceName "paths" .Values.ingress.paths.ruler )}} +{{- end -}} + +{{/* +Ingress service path helper function +Params: + ctx = . context + serviceName = fully qualified k8s service name + paths = list of url paths to allow ingress for +*/}} +{{- define "loki.ingress.servicePath" -}} +{{- $ingressApiIsStable := eq (include "loki.ingress.isStable" .ctx) "true" -}} +{{- $ingressSupportsPathType := eq (include "loki.ingress.supportsPathType" .ctx) "true" -}} +{{- range .paths }} +- path: {{ . }} + {{- if $ingressSupportsPathType }} + pathType: Prefix + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $.serviceName }} + port: + number: {{ $.ctx.Values.loki.server.http_listen_port }} + {{- else }} + serviceName: {{ $.serviceName }} + servicePort: {{ $.ctx.Values.loki.server.http_listen_port }} + {{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create the service endpoint including port for MinIO. +*/}} +{{- define "loki.minio" -}} +{{- if .Values.minio.enabled -}} +{{- .Values.minio.address | default (printf "%s-%s.%s.svc:%s" .Release.Name "minio" .Release.Namespace (.Values.minio.service.port | toString)) -}} +{{- end -}} +{{- end -}} + +{{/* Determine if deployment is using object storage */}} +{{- define "loki.isUsingObjectStorage" -}} +{{- or (eq .Values.loki.storage.type "gcs") (eq .Values.loki.storage.type "s3") (eq .Values.loki.storage.type "azure") (eq .Values.loki.storage.type "swift") (eq .Values.loki.storage.type "alibabacloud") -}} +{{- end -}} + +{{/* Configure the correct name for the memberlist service */}} +{{- define "loki.memberlist" -}} +{{ include "loki.name" . }}-memberlist +{{- end -}} + +{{/* Determine the public host for the Loki cluster */}} +{{- define "loki.host" -}} +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- $url := printf "%s.%s.svc.%s.:%s" (include "loki.gatewayFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.gateway.service.port | toString) }} +{{- if and $isSingleBinary (not .Values.gateway.enabled) }} + {{- $url = printf "%s.%s.svc.%s.:%s" (include "loki.singleBinaryFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} +{{- end }} +{{- printf "%s" $url -}} +{{- end -}} + +{{/* Determine the public endpoint for the Loki cluster */}} +{{- define "loki.address" -}} +{{- printf "http://%s" (include "loki.host" . ) -}} +{{- end -}} + +{{/* Name of the cluster */}} +{{- define "loki.clusterName" -}} +{{- $name := .Values.enterprise.cluster_name | default .Release.Name }} +{{- printf "%s" $name -}} +{{- end -}} + +{{/* Name of kubernetes secret to persist GEL admin token to */}} +{{- define "enterprise-logs.adminTokenSecret" }} +{{- .Values.enterprise.adminToken.secret | default (printf "%s-admin-token" (include "loki.name" . )) -}} +{{- end -}} + +{{/* Prefix for provisioned secrets created for each provisioned tenant */}} +{{- define "enterprise-logs.provisionedSecretPrefix" }} +{{- .Values.enterprise.provisioner.provisionedSecretPrefix | default (printf "%s-provisioned" (include "loki.name" . )) -}} +{{- end -}} + +{{/* Name of kubernetes secret to persist canary credentials in */}} +{{- define "enterprise-logs.selfMonitoringTenantSecret" }} +{{- .Values.enterprise.canarySecret | default (printf "%s-%s" (include "enterprise-logs.provisionedSecretPrefix" . ) .Values.monitoring.selfMonitoring.tenant.name) -}} +{{- end -}} + +{{/* Snippet for the nginx file used by gateway */}} +{{- define "loki.nginxFile" }} +worker_processes 5; ## Default: 1 +error_log /dev/stderr; +pid /tmp/nginx.pid; +worker_rlimit_nofile 8192; + +events { + worker_connections 4096; ## Default: 1024 +} + +http { + client_body_temp_path /tmp/client_temp; + proxy_temp_path /tmp/proxy_temp_path; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + client_max_body_size {{ .Values.gateway.nginxConfig.clientMaxBodySize }}; + + proxy_read_timeout 600; ## 10 minutes + proxy_send_timeout 600; + proxy_connect_timeout 600; + + proxy_http_version 1.1; + + default_type application/octet-stream; + log_format {{ .Values.gateway.nginxConfig.logFormat }} + + {{- if .Values.gateway.verboseLogging }} + access_log /dev/stderr main; + {{- else }} + + map $status $loggable { + ~^[23] 0; + default 1; + } + access_log /dev/stderr main if=$loggable; + {{- end }} + + sendfile on; + tcp_nopush on; + {{- if .Values.gateway.nginxConfig.resolver }} + resolver {{ .Values.gateway.nginxConfig.resolver }}; + {{- else }} + resolver {{ .Values.global.dnsService }}.{{ .Values.global.dnsNamespace }}.svc.{{ .Values.global.clusterDomain }}.; + {{- end }} + + {{- with .Values.gateway.nginxConfig.httpSnippet }} + {{- tpl . $ | nindent 2 }} + {{- end }} + + server { + {{- if (.Values.gateway.nginxConfig.ssl) }} + listen 8080 ssl; + {{- if .Values.gateway.nginxConfig.enableIPv6 }} + listen [::]:8080 ssl; + {{- end }} + {{- else }} + listen 8080; + {{- if .Values.gateway.nginxConfig.enableIPv6 }} + listen [::]:8080; + {{- end }} + {{- end }} + + {{- if .Values.gateway.basicAuth.enabled }} + auth_basic "Loki"; + auth_basic_user_file /etc/nginx/secrets/.htpasswd; + {{- end }} + + location = / { + return 200 'OK'; + auth_basic off; + } + + ######################################################## + # Configure backend targets + + {{- $backendHost := include "loki.backendFullname" .}} + {{- $readHost := include "loki.readFullname" .}} + {{- $writeHost := include "loki.writeFullname" .}} + + {{- if .Values.read.legacyReadTarget }} + {{- $backendHost = include "loki.readFullname" . }} + {{- end }} + + {{- $httpSchema := .Values.gateway.nginxConfig.schema }} + + {{- $writeUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $writeHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $readUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $readHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $backendUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $backendHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + + {{- if .Values.gateway.nginxConfig.customWriteUrl }} + {{- $writeUrl = .Values.gateway.nginxConfig.customWriteUrl }} + {{- end }} + {{- if .Values.gateway.nginxConfig.customReadUrl }} + {{- $readUrl = .Values.gateway.nginxConfig.customReadUrl }} + {{- end }} + {{- if .Values.gateway.nginxConfig.customBackendUrl }} + {{- $backendUrl = .Values.gateway.nginxConfig.customBackendUrl }} + {{- end }} + + {{- $singleBinaryHost := include "loki.singleBinaryFullname" . }} + {{- $singleBinaryUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $singleBinaryHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + + {{- $distributorHost := include "loki.distributorFullname" .}} + {{- $ingesterHost := include "loki.ingesterFullname" .}} + {{- $queryFrontendHost := include "loki.queryFrontendFullname" .}} + {{- $indexGatewayHost := include "loki.indexGatewayFullname" .}} + {{- $rulerHost := include "loki.rulerFullname" .}} + {{- $compactorHost := include "loki.compactorFullname" .}} + {{- $schedulerHost := include "loki.querySchedulerFullname" .}} + + + {{- $distributorUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $distributorHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) -}} + {{- $ingesterUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $ingesterHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $queryFrontendUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $queryFrontendHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $indexGatewayUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $indexGatewayHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $rulerUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $rulerHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $compactorUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $compactorHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $schedulerUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $schedulerHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + + {{- if eq (include "loki.deployment.isSingleBinary" .) "true"}} + {{- $distributorUrl = $singleBinaryUrl }} + {{- $ingesterUrl = $singleBinaryUrl }} + {{- $queryFrontendUrl = $singleBinaryUrl }} + {{- $indexGatewayUrl = $singleBinaryUrl }} + {{- $rulerUrl = $singleBinaryUrl }} + {{- $compactorUrl = $singleBinaryUrl }} + {{- $schedulerUrl = $singleBinaryUrl }} + {{- else if eq (include "loki.deployment.isScalable" .) "true"}} + {{- $distributorUrl = $writeUrl }} + {{- $ingesterUrl = $writeUrl }} + {{- $queryFrontendUrl = $readUrl }} + {{- $indexGatewayUrl = $backendUrl }} + {{- $rulerUrl = $backendUrl }} + {{- $compactorUrl = $backendUrl }} + {{- $schedulerUrl = $backendUrl }} + {{- end -}} + + {{- if .Values.loki.ui.gateway.enabled }} + location ^~ /ui { + proxy_pass {{ $distributorUrl }}$request_uri; + } + {{- end }} + + # Distributor + location = /api/prom/push { + proxy_pass {{ $distributorUrl }}$request_uri; + } + location = /loki/api/v1/push { + proxy_pass {{ $distributorUrl }}$request_uri; + } + location = /distributor/ring { + proxy_pass {{ $distributorUrl }}$request_uri; + } + location = /otlp/v1/logs { + proxy_pass {{ $distributorUrl }}$request_uri; + } + + # Ingester + location = /flush { + proxy_pass {{ $ingesterUrl }}$request_uri; + } + location ^~ /ingester/ { + proxy_pass {{ $ingesterUrl }}$request_uri; + } + location = /ingester { + internal; # to suppress 301 + } + + # Ring + location = /ring { + proxy_pass {{ $ingesterUrl }}$request_uri; + } + + # MemberListKV + location = /memberlist { + proxy_pass {{ $ingesterUrl }}$request_uri; + } + + # Ruler + location = /ruler/ring { + proxy_pass {{ $rulerUrl }}$request_uri; + } + location = /api/prom/rules { + proxy_pass {{ $rulerUrl }}$request_uri; + } + location ^~ /api/prom/rules/ { + proxy_pass {{ $rulerUrl }}$request_uri; + } + location = /loki/api/v1/rules { + proxy_pass {{ $rulerUrl }}$request_uri; + } + location ^~ /loki/api/v1/rules/ { + proxy_pass {{ $rulerUrl }}$request_uri; + } + location = /prometheus/api/v1/alerts { + proxy_pass {{ $rulerUrl }}$request_uri; + } + location = /prometheus/api/v1/rules { + proxy_pass {{ $rulerUrl }}$request_uri; + } + + # Compactor + location = /compactor/ring { + proxy_pass {{ $compactorUrl }}$request_uri; + } + location = /loki/api/v1/delete { + proxy_pass {{ $compactorUrl }}$request_uri; + } + location = /loki/api/v1/cache/generation_numbers { + proxy_pass {{ $compactorUrl }}$request_uri; + } + + # IndexGateway + location = /indexgateway/ring { + proxy_pass {{ $indexGatewayUrl }}$request_uri; + } + + # QueryScheduler + location = /scheduler/ring { + proxy_pass {{ $schedulerUrl }}$request_uri; + } + + # Config + location = /config { + proxy_pass {{ $ingesterUrl }}$request_uri; + } + + {{- if and .Values.enterprise.enabled .Values.enterprise.adminApi.enabled }} + # Admin API + location ^~ /admin/api/ { + proxy_pass {{ $backendUrl }}$request_uri; + } + location = /admin/api { + internal; # to suppress 301 + } + {{- end }} + + + # QueryFrontend, Querier + location = /api/prom/tail { + proxy_pass {{ $queryFrontendUrl }}$request_uri; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + location = /loki/api/v1/tail { + proxy_pass {{ $queryFrontendUrl }}$request_uri; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + location ^~ /api/prom/ { + proxy_pass {{ $queryFrontendUrl }}$request_uri; + } + location = /api/prom { + internal; # to suppress 301 + } + # if the X-Query-Tags header is empty, set a noop= without a value as empty values are not logged + set $query_tags $http_x_query_tags; + if ($query_tags !~* '') { + set $query_tags "noop="; + } + location ^~ /loki/api/v1/ { + # pass custom headers set by Grafana as X-Query-Tags which are logged as key/value pairs in metrics.go log messages + proxy_set_header X-Query-Tags "${query_tags},user=${http_x_grafana_user},dashboard_id=${http_x_dashboard_uid},dashboard_title=${http_x_dashboard_title},panel_id=${http_x_panel_id},panel_title=${http_x_panel_title},source_rule_uid=${http_x_rule_uid},rule_name=${http_x_rule_name},rule_folder=${http_x_rule_folder},rule_version=${http_x_rule_version},rule_source=${http_x_rule_source},rule_type=${http_x_rule_type}"; + proxy_pass {{ $queryFrontendUrl }}$request_uri; + } + location = /loki/api/v1 { + internal; # to suppress 301 + } + + {{- with .Values.gateway.nginxConfig.serverSnippet }} + {{ . | nindent 4 }} + {{- end }} + } +} +{{- end }} + +{{/* Configure enableServiceLinks in pod */}} +{{- define "loki.enableServiceLinks" -}} +{{- if semverCompare ">=1.13-0" (include "loki.kubeVersion" .) -}} +{{- if or (.Values.loki.enableServiceLinks) (ne .Values.loki.enableServiceLinks false) -}} +enableServiceLinks: true +{{- else -}} +enableServiceLinks: false +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* Determine compactor address based on target configuration */}} +{{- define "loki.compactorAddress" -}} +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- $compactorAddress := include "loki.backendFullname" . -}} +{{- if and $isSimpleScalable .Values.read.legacyReadTarget -}} +{{/* 2 target configuration */}} +{{- $compactorAddress = include "loki.readFullname" . -}} +{{- else if $isSingleBinary -}} +{{/* single binary */}} +{{- $compactorAddress = include "loki.singleBinaryFullname" . -}} +{{/* distributed */}} +{{- else if $isDistributed -}} +{{- $compactorAddress = include "loki.compactorFullname" . -}} +{{- end -}} +{{- printf "http://%s:%s" $compactorAddress (.Values.loki.server.http_listen_port | toString) }} +{{- end }} + +{{/* Determine query-scheduler address */}} +{{- define "loki.querySchedulerAddress" -}} +{{- $schedulerAddress := ""}} +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +{{- $schedulerAddress = printf "%s.%s.svc.%s:%s" (include "loki.querySchedulerFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.grpc_listen_port | toString) -}} +{{- end -}} +{{- printf "%s" $schedulerAddress }} +{{- end }} + +{{/* Determine querier address */}} +{{- define "loki.querierAddress" -}} +{{- $querierAddress := "" }} +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +{{- $querierHost := include "loki.querierFullname" .}} +{{- $querierUrl := printf "http://%s.%s.svc.%s:3100" $querierHost .Release.Namespace .Values.global.clusterDomain }} +{{- $querierAddress = $querierUrl }} +{{- end -}} +{{- printf "%s" $querierAddress }} +{{- end }} + +{{/* Determine index-gateway address */}} +{{- define "loki.indexGatewayAddress" -}} +{{- $idxGatewayAddress := ""}} +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- $isScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isDistributed -}} +{{- $idxGatewayAddress = printf "dns+%s-headless.%s.svc.%s:%s" (include "loki.indexGatewayFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.grpc_listen_port | toString) -}} +{{- end -}} +{{- if $isScalable -}} +{{- $idxGatewayAddress = printf "dns+%s-headless.%s.svc.%s:%s" (include "loki.backendFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.grpc_listen_port | toString) -}} +{{- end -}} +{{- printf "%s" $idxGatewayAddress }} +{{- end }} + +{{/* Determine bloom-planner address */}} +{{- define "loki.bloomPlannerAddress" -}} +{{- $bloomPlannerAddress := ""}} +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- $isScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isDistributed -}} +{{- $bloomPlannerAddress = printf "%s-headless.%s.svc.%s:%s" (include "loki.bloomPlannerFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.grpc_listen_port | toString) -}} +{{- end -}} +{{- if $isScalable -}} +{{- $bloomPlannerAddress = printf "%s-headless.%s.svc.%s:%s" (include "loki.backendFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.grpc_listen_port | toString) -}} +{{- end -}} +{{- printf "%s" $bloomPlannerAddress}} +{{- end }} + +{{/* Determine bloom-gateway address */}} +{{- define "loki.bloomGatewayAddresses" -}} +{{- $bloomGatewayAddresses := ""}} +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- $isScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isDistributed -}} +{{- $bloomGatewayAddresses = printf "dnssrvnoa+_grpc._tcp.%s-headless.%s.svc.%s" (include "loki.bloomGatewayFullname" .) .Release.Namespace .Values.global.clusterDomain -}} +{{- end -}} +{{- if $isScalable -}} +{{- $bloomGatewayAddresses = printf "dnssrvnoa+_grpc._tcp.%s-headless.%s.svc.%s" (include "loki.backendFullname" .) .Release.Namespace .Values.global.clusterDomain -}} +{{- end -}} +{{- printf "%s" $bloomGatewayAddresses}} +{{- end }} + +{{- define "loki.config.checksum" -}} +checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} +{{- end -}} + +{{/* +Return the appropriate apiVersion for PodDisruptionBudget. +*/}} +{{- define "loki.pdb.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "policy/v1") (semverCompare ">=1.21-0" (include "loki.kubeVersion" .)) -}} + {{- print "policy/v1" -}} + {{- else -}} + {{- print "policy/v1beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the object store type for use with the test schema. +*/}} +{{- define "loki.testSchemaObjectStore" -}} + {{- if .Values.minio.enabled -}} + s3 + {{- else -}} + filesystem + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for HorizontalPodAutoscaler. +*/}} +{{- define "loki.hpa.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "autoscaling/v2") (semverCompare ">= 1.19-0" (include "loki.kubeVersion" .)) -}} + {{- print "autoscaling/v2" -}} + {{- else if .Capabilities.APIVersions.Has "autoscaling/v2beta2" -}} + {{- print "autoscaling/v2beta2" -}} + {{- else -}} + {{- print "autoscaling/v2beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +compute a ConfigMap or Secret checksum only based on its .data content. +This function needs to be called with a context object containing the following keys: +- ctx: the current Helm context (what '.' is at the call site) +- name: the file name of the ConfigMap or Secret +*/}} +{{- define "loki.configMapOrSecretContentHash" -}} +{{ get (include (print .ctx.Template.BasePath .name) .ctx | fromYaml) "data" | toYaml | sha256sum }} +{{- end }} + +{{/* Thanos object storage configuration helper to build +the thanos_storage_config model*/}} +{{- define "loki.thanosStorageConfig" -}} +{{- $bucketName := .bucketName }} +{{- with .ctx.Values.loki.storage.object_store }} +{{- if eq .type "s3" }} +s3: + {{- with .s3 }} + bucket_name: {{ $bucketName }} + endpoint: {{ .endpoint }} + access_key_id: {{ .access_key_id }} + secret_access_key: {{ .secret_access_key }} + region: {{ .region }} + insecure: {{ .insecure }} + http: + {{ toYaml .http | nindent 4 }} + sse: + {{ toYaml .sse | nindent 4 }} + {{- end }} +{{- else if eq .type "gcs" }} +gcs: + {{- with .gcs }} + bucket_name: {{ $bucketName }} + service_account: {{ .service_account }} + {{- end }} +{{- else if eq .type "azure" }} +azure: + {{- with .azure }} + container_name: {{ $bucketName }} + account_name: {{ .account_name }} + account_key: {{ .account_key }} + {{- end }} +{{- end }} +storage_prefix: {{ .storage_prefix }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/admin-api/_helpers.yaml b/charts/loki/templates/admin-api/_helpers.yaml new file mode 100644 index 0000000..e13ff8a --- /dev/null +++ b/charts/loki/templates/admin-api/_helpers.yaml @@ -0,0 +1,24 @@ +{{/* +adminApi fullname +*/}} +{{- define "enterprise-logs.adminApiFullname" -}} +{{ include "loki.fullname" . }}-admin-api +{{- end }} + +{{/* +adminApi common labels +*/}} +{{- define "enterprise-logs.adminApiLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: admin-api +target: admin-api +{{- end }} + +{{/* +adminApi selector labels +*/}} +{{- define "enterprise-logs.adminApiSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: admin-api +target: admin-api +{{- end }} \ No newline at end of file diff --git a/charts/loki/templates/admin-api/deployment-admin-api.yaml b/charts/loki/templates/admin-api/deployment-admin-api.yaml new file mode 100644 index 0000000..3331107 --- /dev/null +++ b/charts/loki/templates/admin-api/deployment-admin-api.yaml @@ -0,0 +1,155 @@ +{{- if and .Values.enterprise.enabled .Values.enterprise.adminApi.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "enterprise-logs.adminApiFullname" . }} + labels: + {{- include "enterprise-logs.adminApiLabels" . | nindent 4 }} + {{- with .Values.adminApi.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + app.kubernetes.io/part-of: memberlist + annotations: + {{- with .Values.adminApi.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.adminApi.replicas }} + selector: + matchLabels: + {{- include "enterprise-logs.adminApiSelectorLabels" . | nindent 6 }} + strategy: + {{- toYaml .Values.adminApi.strategy | nindent 4 }} + template: + metadata: + labels: + {{- include "enterprise-logs.adminApiLabels" . | nindent 8 }} + {{- with merge (dict) .Values.loki.podLabels .Values.adminApi.labels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + app.kubernetes.io/part-of: memberlist + annotations: + {{- if .Values.useExternalConfig }} + checksum/config: {{ .Values.externalConfigVersion }} + {{- else }} + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- end}} + {{- with .Values.adminApi.annotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.adminApi.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ template "loki.serviceAccountName" . }} + {{- if .Values.adminApi.priorityClassName }} + priorityClassName: {{ .Values.adminApi.priorityClassName }} + {{- end }} + securityContext: + {{- toYaml .Values.adminApi.podSecurityContext | nindent 8 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.adminApi.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: admin-api + image: "{{ template "loki.image" . }}" + imagePullPolicy: {{ .Values.enterprise.image.pullPolicy }} + args: + - -target=admin-api + - -config.file=/etc/loki/config/config.yaml + {{- if .Values.minio.enabled }} + - -admin.client.backend-type=s3 + - -admin.client.s3.endpoint={{ template "loki.minio" . }} + - -admin.client.s3.bucket-name={{ .Values.loki.storage.bucketNames.admin }} + - -admin.client.s3.access-key-id={{ (index .Values.minio.users 0).accessKey }} + - -admin.client.s3.secret-access-key={{ (index .Values.minio.users 0).secretKey }} + - -admin.client.s3.insecure={{ .Values.loki.storage.s3.insecure }} + {{- end }} + {{- range $key, $value := .Values.adminApi.extraArgs }} + - "-{{ $key }}={{ $value }}" + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: license + mountPath: /etc/loki/license + - name: storage + mountPath: /data + {{- if .Values.adminApi.extraVolumeMounts }} + {{ toYaml .Values.adminApi.extraVolumeMounts | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + readinessProbe: + {{- toYaml .Values.adminApi.readinessProbe | nindent 12 }} + resources: + {{- toYaml .Values.adminApi.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.adminApi.containerSecurityContext | nindent 12 }} + env: + {{- if .Values.adminApi.env }} + {{ toYaml .Values.adminApi.env | nindent 12 }} + {{- end }} + {{- with .Values.adminApi.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.adminApi.extraContainers }} + {{ toYaml . | nindent 8 }} + {{- end }} + nodeSelector: + {{- toYaml .Values.adminApi.nodeSelector | nindent 8 }} + affinity: + {{- toYaml .Values.adminApi.affinity | nindent 8 }} + tolerations: + {{- toYaml .Values.adminApi.tolerations | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.adminApi.terminationGracePeriodSeconds }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + - name: storage + emptyDir: {} + {{- if .Values.adminApi.extraVolumes }} + {{ toYaml .Values.adminApi.extraVolumes | nindent 8 }} + {{- end }} + {{- if .Values.minio.enabled }} + - name: minio-configuration + projected: + sources: + - configMap: + name: {{ .Release.Name }}-minio + - secret: + name: {{ .Release.Name }}-minio + {{- if .Values.minio.tls.enabled }} + - name: cert-secret-volume-mc + secret: + secretName: {{ .Values.minio.tls.certSecret }} + items: + - key: {{ .Values.minio.tls.publicCrt }} + path: CAs/public.crt + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/admin-api/service-admin-api.yaml b/charts/loki/templates/admin-api/service-admin-api.yaml new file mode 100644 index 0000000..8f81723 --- /dev/null +++ b/charts/loki/templates/admin-api/service-admin-api.yaml @@ -0,0 +1,28 @@ +{{- if and .Values.enterprise.enabled .Values.enterprise.adminApi.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "enterprise-logs.adminApiFullname" . }} + labels: + {{- include "enterprise-logs.adminApiLabels" . | nindent 4 }} + {{- with .Values.adminApi.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.adminApi.service.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3100 + protocol: TCP + targetPort: http-metrics + - name: grpc + port: 9095 + protocol: TCP + targetPort: grpc + selector: + {{- include "enterprise-logs.adminApiSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/backend/_helpers-backend.tpl b/charts/loki/templates/backend/_helpers-backend.tpl new file mode 100644 index 0000000..08f5f8f --- /dev/null +++ b/charts/loki/templates/backend/_helpers-backend.tpl @@ -0,0 +1,32 @@ +{{/* +backend fullname +*/}} +{{- define "loki.backendFullname" -}} +{{ include "loki.name" . }}-backend +{{- end }} + +{{/* +backend common labels +*/}} +{{- define "loki.backendLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: backend +{{- end }} + +{{/* +backend selector labels +*/}} +{{- define "loki.backendSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: backend +{{- end }} + +{{/* +backend priority class name +*/}} +{{- define "loki.backendPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.backend.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/backend/clusterrole.yaml b/charts/loki/templates/backend/clusterrole.yaml new file mode 100644 index 0000000..36c8a0f --- /dev/null +++ b/charts/loki/templates/backend/clusterrole.yaml @@ -0,0 +1,20 @@ +{{- if and (not .Values.rbac.namespaced) (not .Values.rbac.useExistingRole) }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "loki.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + name: {{ template "loki.fullname" . }}-clusterrole +{{- if .Values.sidecar.rules.enabled }} +rules: +- apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] +{{- else }} +rules: [] +{{- end }} +{{- end }} diff --git a/charts/loki/templates/backend/clusterrolebinding.yaml b/charts/loki/templates/backend/clusterrolebinding.yaml new file mode 100644 index 0000000..92f86a4 --- /dev/null +++ b/charts/loki/templates/backend/clusterrolebinding.yaml @@ -0,0 +1,25 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if (not .Values.rbac.namespaced) }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "loki.fullname" . }}-clusterrolebinding + labels: + {{- include "loki.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +subjects: + - kind: ServiceAccount + name: {{ template "loki.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole +{{- if (not .Values.rbac.useExistingRole) }} + name: {{ template "loki.fullname" . }}-clusterrole +{{- else }} + name: {{ .Values.rbac.useExistingRole }} +{{- end }} + apiGroup: rbac.authorization.k8s.io +{{- end -}} diff --git a/charts/loki/templates/backend/hpa.yaml b/charts/loki/templates/backend/hpa.yaml new file mode 100644 index 0000000..ea834d6 --- /dev/null +++ b/charts/loki/templates/backend/hpa.yaml @@ -0,0 +1,50 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- $autoscalingv2 := .Capabilities.APIVersions.Has "autoscaling/v2" -}} +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) ( .Values.backend.autoscaling.enabled ) }} +{{- if $autoscalingv2 }} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta1 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.backendFullname" . }} + labels: + {{- include "loki.backendLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.backendFullname" . }} + minReplicas: {{ .Values.backend.autoscaling.minReplicas }} + maxReplicas: {{ .Values.backend.autoscaling.maxReplicas }} + {{- with .Values.backend.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} + metrics: + {{- with .Values.backend.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.backend.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/backend/poddisruptionbudget-backend.yaml b/charts/loki/templates/backend/poddisruptionbudget-backend.yaml new file mode 100644 index 0000000..d8ce5b0 --- /dev/null +++ b/charts/loki/templates/backend/poddisruptionbudget-backend.yaml @@ -0,0 +1,15 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (gt (int .Values.backend.replicas) 1) (not .Values.read.legacyReadTarget ) }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.backendFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.backendLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.backendSelectorLabels" . | nindent 6 }} + maxUnavailable: 1 +{{- end }} diff --git a/charts/loki/templates/backend/query-scheduler-discovery.yaml b/charts/loki/templates/backend/query-scheduler-discovery.yaml new file mode 100644 index 0000000..4c357e5 --- /dev/null +++ b/charts/loki/templates/backend/query-scheduler-discovery.yaml @@ -0,0 +1,34 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.querySchedulerFullname" . }}-discovery + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.backendSelectorLabels" . | nindent 4 }} + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.backend.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + selector: + {{- include "loki.backendSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/backend/service-backend-headless.yaml b/charts/loki/templates/backend/service-backend-headless.yaml new file mode 100644 index 0000000..fd90fdd --- /dev/null +++ b/charts/loki/templates/backend/service-backend-headless.yaml @@ -0,0 +1,41 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.backendFullname" . }}-headless + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.backendSelectorLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.backend.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + variant: headless + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.backend.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + appProtocol: tcp + selector: + {{- include "loki.backendSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/backend/service-backend.yaml b/charts/loki/templates/backend/service-backend.yaml new file mode 100644 index 0000000..cd1bd3b --- /dev/null +++ b/charts/loki/templates/backend/service-backend.yaml @@ -0,0 +1,37 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.backendFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.backendLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.backend.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.backend.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + selector: + {{- include "loki.backendSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/backend/statefulset-backend.yaml b/charts/loki/templates/backend/statefulset-backend.yaml new file mode 100644 index 0000000..6ed122a --- /dev/null +++ b/charts/loki/templates/backend/statefulset-backend.yaml @@ -0,0 +1,281 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.backendFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.backendLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- if or (not (empty .Values.loki.annotations)) (not (empty .Values.backend.annotations))}} + annotations: + {{- with merge (dict) .Values.loki.annotations .Values.backend.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: +{{- if not .Values.backend.autoscaling.enabled }} + {{- if eq .Values.deploymentMode "SingleBinary" }} + replicas: 0 + {{- else }} + replicas: {{ .Values.backend.replicas }} + {{- end }} +{{- end }} + podManagementPolicy: {{ .Values.backend.podManagementPolicy }} + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.backendFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.backend.persistence.enableStatefulSetAutoDeletePVC) (.Values.backend.persistence.volumeClaimsEnabled) }} + {{/* + Data on the backend nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete + {{- end }} + selector: + matchLabels: + {{- include "loki.backendSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.backend.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.backendLabels" . | nindent 8 }} + {{- with merge (dict) .Values.loki.podLabels .Values.backend.podLabels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + app.kubernetes.io/part-of: memberlist + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.backendPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.backend.terminationGracePeriodSeconds }} + {{- if .Values.backend.initContainers }} + initContainers: + {{- with .Values.backend.initContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + containers: + {{- if .Values.sidecar.rules.enabled }} + - name: loki-sc-rules + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.image.pullPolicy }} + env: + - name: METHOD + value: {{ .Values.sidecar.rules.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.rules.label }}" + {{- if .Values.sidecar.rules.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.rules.labelValue }} + {{- end }} + - name: FOLDER + value: "{{ .Values.sidecar.rules.folder }}" + - name: RESOURCE + value: {{ quote .Values.sidecar.rules.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.rules.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.rules.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + {{- if .Values.sidecar.rules.script }} + - name: SCRIPT + value: "{{ .Values.sidecar.rules.script }}" + {{- end }} + {{- if .Values.sidecar.rules.watchServerTimeout }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.rules.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.rules.watchClientTimeout }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.rules.watchClientTimeout }}" + {{- end }} + {{- if .Values.sidecar.rules.logLevel }} + - name: LOG_LEVEL + value: "{{ .Values.sidecar.rules.logLevel }}" + {{- end }} + {{- if .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml .Values.sidecar.livenessProbe | nindent 12 }} + {{- end }} + {{- if .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml .Values.sidecar.readinessProbe | nindent 12 }} + {{- end }} + {{- if .Values.sidecar.resources }} + resources: + {{- toYaml .Values.sidecar.resources | nindent 12 }} + {{- end }} + {{- if .Values.sidecar.securityContext }} + securityContext: + {{- toYaml .Values.sidecar.securityContext | nindent 12 }} + {{- end }} + volumeMounts: + - name: sc-rules-volume + mountPath: {{ .Values.sidecar.rules.folder | quote }} + {{- end}} + - name: loki + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target={{ .Values.backend.targetModule }} + - -legacy-read-mode=false + {{- with (concat .Values.global.extraArgs .Values.backend.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.loki.server.http_listen_port }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.loki.server.grpc_listen_port }} + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.backend.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnv .Values.backend.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: tmp + mountPath: /tmp + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end}} + {{- if .Values.sidecar.rules.enabled }} + - name: sc-rules-volume + mountPath: {{ .Values.sidecar.rules.folder | quote }} + {{- end}} + {{- with (concat .Values.global.extraVolumeMounts .Values.backend.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.backend.resources | nindent 12 }} + {{- with .Values.backend.extraContainers }} + {{- toYaml . | nindent 8}} + {{- end }} + {{- with .Values.backend.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.backend.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.backend.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.backend.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.backend.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: tmp + emptyDir: {} + {{- if not .Values.backend.persistence.volumeClaimsEnabled }} + - name: data + {{- toYaml .Values.backend.persistence.dataVolumeParameters | nindent 10 }} + {{- end}} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- if .Values.sidecar.rules.enabled }} + - name: sc-rules-volume + {{- if .Values.sidecar.rules.sizeLimit }} + emptyDir: + sizeLimit: {{ .Values.sidecar.rules.sizeLimit }} + {{- else }} + emptyDir: {} + {{- end -}} + {{- end -}} + {{- with (concat .Values.global.extraVolumes .Values.backend.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.backend.persistence.volumeClaimsEnabled }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + {{- with .Values.backend.persistence.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.backend.persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .Values.backend.persistence.size | quote }} + {{- with .Values.backend.persistence.selector }} + selector: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/bloom-builder/_helpers-bloom-builder.tpl b/charts/loki/templates/bloom-builder/_helpers-bloom-builder.tpl new file mode 100644 index 0000000..46359df --- /dev/null +++ b/charts/loki/templates/bloom-builder/_helpers-bloom-builder.tpl @@ -0,0 +1,32 @@ +{{/* +bloom-builder fullname +*/}} +{{- define "loki.bloomBuilderFullname" -}} +{{ include "loki.fullname" . }}-bloom-builder +{{- end }} + +{{/* +bloom-builder common labels +*/}} +{{- define "loki.bloomBuilderLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: bloom-builder +{{- end }} + +{{/* +bloom-builder selector labels +*/}} +{{- define "loki.bloomBuilderSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: bloom-builder +{{- end }} + +{{/* +bloom-builder priority class name +*/}} +{{- define "loki.bloomBuilderPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.bloomBuilder.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/bloom-builder/deployment-bloom-builder.yaml b/charts/loki/templates/bloom-builder/deployment-bloom-builder.yaml new file mode 100644 index 0000000..c7f4513 --- /dev/null +++ b/charts/loki/templates/bloom-builder/deployment-bloom-builder.yaml @@ -0,0 +1,147 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if (and $isDistributed (gt (int .Values.bloomPlanner.replicas) 0)) -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.bloomBuilderFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomBuilderLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.bloomBuilder.autoscaling.enabled }} + replicas: {{ .Values.bloomBuilder.replicas }} +{{- end }} + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.bloomBuilderSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomBuilder.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.bloomBuilderLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.bloomBuilder.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomBuilder.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.bloomBuilderPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.bloomBuilder.terminationGracePeriodSeconds }} + containers: + - name: bloom-builder + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.bloomBuilder.command }} + command: + - {{ coalesce .Values.bloomBuilder.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=bloom-builder + {{- with (concat .Values.global.extraArgs .Values.bloomBuilder.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.bloomBuilder.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.bloomBuilder.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + - name: temp + mountPath: /tmp + - name: data + mountPath: /var/loki + {{- with (concat .Values.global.extraVolumeMounts .Values.bloomBuilder.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.bloomBuilder.resources | nindent 12 }} + {{- if .Values.bloomBuilder.extraContainers }} + {{- toYaml .Values.bloomBuilder.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.bloomBuilder.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomBuilder.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomBuilder.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + - name: temp + emptyDir: {} + - name: data + emptyDir: {} + {{- with (concat .Values.global.extraVolumes .Values.bloomBuilder.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end -}} diff --git a/charts/loki/templates/bloom-builder/hpa.yaml b/charts/loki/templates/bloom-builder/hpa.yaml new file mode 100644 index 0000000..2b04647 --- /dev/null +++ b/charts/loki/templates/bloom-builder/hpa.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.bloomBuilder.autoscaling.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.bloomBuilderFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomBuilderLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "loki.bloomBuilderFullname" . }} + minReplicas: {{ .Values.bloomBuilder.autoscaling.minReplicas }} + maxReplicas: {{ .Values.bloomBuilder.autoscaling.maxReplicas }} + metrics: + {{- with .Values.bloomBuilder.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.bloomBuilder.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.bloomBuilder.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.bloomBuilder.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.bloomBuilder.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.bloomBuilder.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/bloom-builder/poddisruptionbudget-bloom-builder.yaml b/charts/loki/templates/bloom-builder/poddisruptionbudget-bloom-builder.yaml new file mode 100644 index 0000000..e66d762 --- /dev/null +++ b/charts/loki/templates/bloom-builder/poddisruptionbudget-bloom-builder.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.bloomBuilder.replicas) 1) }} +{{- if kindIs "invalid" .Values.bloomBuilder.maxUnavailable }} +{{- fail "`.Values.bloomBuilder.maxUnavailable` must be set when `.Values.bloomBuilder.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.bloomBuilderFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomBuilderLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.bloomBuilderSelectorLabels" . | nindent 6 }} + {{- with .Values.bloomBuilder.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/bloom-builder/service-bloom-builder-headless.yaml b/charts/loki/templates/bloom-builder/service-bloom-builder-headless.yaml new file mode 100644 index 0000000..9389252 --- /dev/null +++ b/charts/loki/templates/bloom-builder/service-bloom-builder-headless.yaml @@ -0,0 +1,46 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if (and $isDistributed (or (gt (int .Values.bloomBuilder.replicas) 0)) .Values.bloomBuilder.autoscaling.enabled) -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.bloomBuilderFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomBuilderLabels" . | nindent 4 }} + {{- with .Values.bloomBuilder.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.bloomBuilder.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + type: ClusterIP + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.bloomBuilder.appProtocol.grpc }} + appProtocol: {{ .Values.bloomBuilder.appProtocol.grpc }} + {{- end }} + - name: grpclb + port: 9096 + targetPort: grpc + protocol: TCP + {{- if .Values.bloomBuilder.appProtocol.grpc }} + appProtocol: {{ .Values.bloomBuilder.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.bloomBuilderSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/templates/bloom-builder/service-bloom-builder.yaml b/charts/loki/templates/bloom-builder/service-bloom-builder.yaml new file mode 100644 index 0000000..b3debb0 --- /dev/null +++ b/charts/loki/templates/bloom-builder/service-bloom-builder.yaml @@ -0,0 +1,44 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if (and $isDistributed (gt (int .Values.bloomBuilder.replicas) 0)) -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.bloomBuilderFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomBuilderLabels" . | nindent 4 }} + {{- with .Values.bloomBuilder.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.bloomBuilder.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.bloomBuilder.appProtocol.grpc }} + appProtocol: {{ .Values.bloomBuilder.appProtocol.grpc }} + {{- end }} + - name: grpclb + port: 9096 + targetPort: grpc + protocol: TCP + {{- if .Values.bloomBuilder.appProtocol.grpc }} + appProtocol: {{ .Values.bloomBuilder.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.bloomBuilderSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/templates/bloom-gateway/_helpers-bloom-gateway.tpl b/charts/loki/templates/bloom-gateway/_helpers-bloom-gateway.tpl new file mode 100644 index 0000000..f0cef4f --- /dev/null +++ b/charts/loki/templates/bloom-gateway/_helpers-bloom-gateway.tpl @@ -0,0 +1,58 @@ +{{/* +bloom gateway fullname +*/}} +{{- define "loki.bloomGatewayFullname" -}} +{{ include "loki.fullname" . }}-bloom-gateway +{{- end }} + +{{/* +bloom gateway common labels +*/}} +{{- define "loki.bloomGatewayLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: bloom-gateway +{{- end }} + +{{/* +bloom gateway selector labels +*/}} +{{- define "loki.bloomGatewaySelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: bloom-gateway +{{- end }} + +{{/* +bloom gateway readinessProbe +*/}} +{{- define "loki.bloomGateway.readinessProbe" -}} +{{- with .Values.bloomGateway.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +bloom gateway priority class name +*/}} +{{- define "loki.bloomGatewayPriorityClassName" }} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.bloomGateway.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} + +{{/* +Create the name of the bloom gateway service account +*/}} +{{- define "loki.bloomGatewayServiceAccountName" -}} +{{- if .Values.bloomGateway.serviceAccount.create -}} + {{ default (print (include "loki.serviceAccountName" .) "-bloom-gateway") .Values.bloomGateway.serviceAccount.name }} +{{- else -}} + {{ default (include "loki.serviceAccountName" .) .Values.bloomGateway.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/bloom-gateway/service-bloom-gateway-headless.yaml b/charts/loki/templates/bloom-gateway/service-bloom-gateway-headless.yaml new file mode 100644 index 0000000..852e4cb --- /dev/null +++ b/charts/loki/templates/bloom-gateway/service-bloom-gateway-headless.yaml @@ -0,0 +1,39 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +{{- if (gt (int .Values.bloomGateway.replicas) 0) -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.bloomGatewayFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomGatewaySelectorLabels" . | nindent 4 }} + {{- with .Values.bloomGateway.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.bloomGateway.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.bloomGateway.appProtocol.grpc }} + appProtocol: {{ .Values.bloomGateway.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.bloomGatewaySelectorLabels" . | nindent 4 }} +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/bloom-gateway/statefulset-bloom-gateway.yaml b/charts/loki/templates/bloom-gateway/statefulset-bloom-gateway.yaml new file mode 100644 index 0000000..9da0f9f --- /dev/null +++ b/charts/loki/templates/bloom-gateway/statefulset-bloom-gateway.yaml @@ -0,0 +1,180 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if (and $isDistributed (gt (int .Values.bloomGateway.replicas) 0)) -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.bloomGatewayFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomGatewayLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.bloomGateway.replicas }} + podManagementPolicy: Parallel + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.bloomGatewayFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.bloomGateway.persistence.enableStatefulSetAutoDeletePVC) }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.bloomGateway.persistence.whenDeleted }} + whenScaled: {{ .Values.bloomGateway.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.bloomGatewaySelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomGateway.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.bloomGatewayLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.bloomGateway.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomGateway.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.bloomGatewayPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.bloomGateway.terminationGracePeriodSeconds }} + {{- with .Values.bloomGateway.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: bloom-gateway + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.bloomGateway.command }} + command: + - {{ coalesce .Values.bloomGateway.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=bloom-gateway + {{- with (concat .Values.global.extraArgs .Values.bloomGateway.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.bloomGateway.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.bloomGateway.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.bloomGateway.readinessProbe" . | nindent 10 }} + volumeMounts: + - name: temp + mountPath: /tmp + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.bloomGateway.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.bloomGateway.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.bloomGateway.extraContainers }} + {{- toYaml .Values.bloomGateway.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.bloomGateway.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomGateway.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomGateway.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: temp + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- if not .Values.bloomGateway.persistence.enabled }} + - name: data + emptyDir: {} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.bloomGateway.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.bloomGateway.persistence.enabled }} + volumeClaimTemplates: + {{- range .Values.bloomGateway.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/loki/templates/bloom-planner/_helpers-bloom-planner.tpl b/charts/loki/templates/bloom-planner/_helpers-bloom-planner.tpl new file mode 100644 index 0000000..a4a8c6e --- /dev/null +++ b/charts/loki/templates/bloom-planner/_helpers-bloom-planner.tpl @@ -0,0 +1,58 @@ +{{/* +bloom planner fullname +*/}} +{{- define "loki.bloomPlannerFullname" -}} +{{ include "loki.fullname" . }}-bloom-planner +{{- end }} + +{{/* +bloom planner common labels +*/}} +{{- define "loki.bloomPlannerLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: bloom-planner +{{- end }} + +{{/* +bloom planner selector labels +*/}} +{{- define "loki.bloomPlannerSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: bloom-planner +{{- end }} + +{{/* +bloom planner readinessProbe +*/}} +{{- define "loki.bloomPlanner.readinessProbe" -}} +{{- with .Values.bloomPlanner.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +bloom planner priority class name +*/}} +{{- define "loki.bloomPlannerPriorityClassName" }} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.bloomPlanner.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} + +{{/* +Create the name of the bloom planner service account +*/}} +{{- define "loki.bloomPlannerServiceAccountName" -}} +{{- if .Values.bloomPlanner.serviceAccount.create -}} + {{ default (print (include "loki.serviceAccountName" .) "-bloom-planner") .Values.bloomPlanner.serviceAccount.name }} +{{- else -}} + {{ default (include "loki.serviceAccountName" .) .Values.bloomPlanner.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/bloom-planner/service-bloom-planner-headless.yaml b/charts/loki/templates/bloom-planner/service-bloom-planner-headless.yaml new file mode 100644 index 0000000..78e2633 --- /dev/null +++ b/charts/loki/templates/bloom-planner/service-bloom-planner-headless.yaml @@ -0,0 +1,37 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if (and $isDistributed (gt (int .Values.bloomPlanner.replicas) 0)) -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.bloomPlannerFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomPlannerSelectorLabels" . | nindent 4 }} + {{- with .Values.bloomPlanner.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.bloomPlanner.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.bloomPlanner.appProtocol.grpc }} + appProtocol: {{ .Values.bloomPlanner.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.bloomPlannerSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/templates/bloom-planner/statefulset-bloom-planner.yaml b/charts/loki/templates/bloom-planner/statefulset-bloom-planner.yaml new file mode 100644 index 0000000..349765d --- /dev/null +++ b/charts/loki/templates/bloom-planner/statefulset-bloom-planner.yaml @@ -0,0 +1,180 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if (and $isDistributed (gt (int .Values.bloomPlanner.replicas) 0)) -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.bloomPlannerFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomPlannerLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.bloomPlanner.replicas }} + podManagementPolicy: Parallel + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.bloomPlannerFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.bloomPlanner.persistence.enableStatefulSetAutoDeletePVC) }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.bloomPlanner.persistence.whenDeleted }} + whenScaled: {{ .Values.bloomPlanner.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.bloomPlannerSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomPlanner.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.bloomPlannerLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.bloomPlanner.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomPlanner.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.bloomPlannerPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.bloomPlanner.terminationGracePeriodSeconds }} + {{- with .Values.bloomPlanner.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: bloom-planner + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.bloomPlanner.command }} + command: + - {{ coalesce .Values.bloomPlanner.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=bloom-planner + {{- with .Values.bloomPlanner.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with .Values.bloomPlanner.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.bloomPlanner.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.bloomPlanner.readinessProbe" . | nindent 10 }} + volumeMounts: + - name: temp + mountPath: /tmp + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with .Values.bloomPlanner.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.bloomPlanner.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.bloomPlanner.extraContainers }} + {{- toYaml .Values.bloomPlanner.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.bloomPlanner.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomPlanner.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomPlanner.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: temp + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- if not .Values.bloomPlanner.persistence.enabled }} + - name: data + emptyDir: {} + {{- end }} + {{- with .Values.bloomPlanner.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.bloomPlanner.persistence.enabled }} + volumeClaimTemplates: + {{- range .Values.bloomPlanner.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/loki/templates/chunks-cache/poddisruptionbudget-chunks-cache.yaml b/charts/loki/templates/chunks-cache/poddisruptionbudget-chunks-cache.yaml new file mode 100644 index 0000000..da95adf --- /dev/null +++ b/charts/loki/templates/chunks-cache/poddisruptionbudget-chunks-cache.yaml @@ -0,0 +1,16 @@ +{{- if .Values.chunksCache.enabled }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.fullname" . }}-memcached-chunks-cache + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: memcached-chunks-cache +spec: + selector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: memcached-chunks-cache + maxUnavailable: 1 +{{- end -}} diff --git a/charts/loki/templates/chunks-cache/service-chunks-cache-headless.yaml b/charts/loki/templates/chunks-cache/service-chunks-cache-headless.yaml new file mode 100644 index 0000000..dc2ccd4 --- /dev/null +++ b/charts/loki/templates/chunks-cache/service-chunks-cache-headless.yaml @@ -0,0 +1 @@ +{{- include "loki.memcached.service" (dict "ctx" $ "valuesSection" "chunksCache" "component" "chunks-cache" ) }} diff --git a/charts/loki/templates/chunks-cache/statefulset-chunks-cache.yaml b/charts/loki/templates/chunks-cache/statefulset-chunks-cache.yaml new file mode 100644 index 0000000..6a54c57 --- /dev/null +++ b/charts/loki/templates/chunks-cache/statefulset-chunks-cache.yaml @@ -0,0 +1 @@ +{{- include "loki.memcached.statefulSet" (dict "ctx" $ "valuesSection" "chunksCache" "component" "chunks-cache" ) }} diff --git a/charts/loki/templates/ciliumnetworkpolicy.yaml b/charts/loki/templates/ciliumnetworkpolicy.yaml new file mode 100644 index 0000000..fbd2619 --- /dev/null +++ b/charts/loki/templates/ciliumnetworkpolicy.yaml @@ -0,0 +1,238 @@ +{{- if and (.Values.networkPolicy.enabled) (eq .Values.networkPolicy.flavor "cilium") }} +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-namespace-only + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: {} + egress: + - toEndpoints: + - {} + ingress: + - fromEndpoints: + - {} + +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-dns + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + egress: + - toPorts: + - ports: + - port: dns + protocol: UDP + toEndpoints: + - namespaceSelector: {} + +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-ingress + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: + matchExpressions: + - key: app.kubernetes.io/component + operator: In + values: + {{- if .Values.gateway.enabled }} + - gateway + {{- else }} + - read + - write + {{- end }} + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + ingress: + - toPorts: + - ports: + - port: http + protocol: TCP + {{- if .Values.networkPolicy.ingress.namespaceSelector }} + fromEndpoints: + - matchLabels: + {{- toYaml .Values.networkPolicy.ingress.namespaceSelector | nindent 8 }} + {{- if .Values.networkPolicy.ingress.podSelector }} + {{- toYaml .Values.networkPolicy.ingress.podSelector | nindent 8 }} + {{- end }} + {{- end }} + +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-ingress-metrics + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + ingress: + - toPorts: + - ports: + - port: http-metrics + protocol: TCP + {{- if .Values.networkPolicy.metrics.cidrs }} + {{- range $cidr := .Values.networkPolicy.metrics.cidrs }} + toCIDR: + - {{ $cidr }} + {{- end }} + {{- if .Values.networkPolicy.metrics.namespaceSelector }} + fromEndpoints: + - matchLabels: + {{- toYaml .Values.networkPolicy.metrics.namespaceSelector | nindent 8 }} + {{- if .Values.networkPolicy.metrics.podSelector }} + {{- toYaml .Values.networkPolicy.metrics.podSelector | nindent 8 }} + {{- end }} + {{- end }} + {{- end }} + +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-alertmanager + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: + matchLabels: + {{- include "loki.backendSelectorLabels" . | nindent 6 }} + egress: + - toPorts: + - ports: + - port: "{{ .Values.networkPolicy.alertmanager.port }}" + protocol: TCP + {{- if .Values.networkPolicy.alertmanager.namespaceSelector }} + toEndpoints: + - matchLabels: + {{- toYaml .Values.networkPolicy.alertmanager.namespaceSelector | nindent 8 }} + {{- if .Values.networkPolicy.alertmanager.podSelector }} + {{- toYaml .Values.networkPolicy.alertmanager.podSelector | nindent 8 }} + {{- end }} + {{- end }} + +{{- if .Values.networkPolicy.externalStorage.ports }} +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-external-storage + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + egress: + - toPorts: + - ports: + {{- range $port := .Values.networkPolicy.externalStorage.ports }} + - port: "{{ $port }}" + protocol: TCP + {{- end }} + {{- if .Values.networkPolicy.externalStorage.cidrs }} + {{- range $cidr := .Values.networkPolicy.externalStorage.cidrs }} + toCIDR: + - {{ $cidr }} + {{- end }} + {{- end }} +{{- end }} + +{{- if .Values.networkPolicy.egressWorld.enabled }} +{{- $global := . }} +{{- $componentsList := list "read" "write" "backend" }} +{{- if .Values.tableManager.enabled }} +{{- $componentsList = append $componentsList "table-manager" }} +{{- end }} +{{- range $component := $componentsList }} +{{- with $global }} +--- +apiVersion: "cilium.io/v2" +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-{{ $component }}-world-egress + namespace: {{ .Release.Namespace }} +spec: + endpointSelector: + matchLabels: + {{- if eq $component "read" }} + {{- include "loki.readSelectorLabels" . | nindent 6 }} + {{- else if eq $component "write" }} + {{- include "loki.writeSelectorLabels" . | nindent 6 }} + {{- else if eq $component "table-manager" }} + {{- include "loki.tableManagerSelectorLabels" . | nindent 6 }} + {{- else }} + {{- include "loki.backendSelectorLabels" . | nindent 6 }} + {{- end }} + egress: + - toEntities: + - world +{{- end }} +{{- end }} +{{- end }} + +{{- if .Values.networkPolicy.egressKubeApiserver.enabled }} +--- +apiVersion: "cilium.io/v2" +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-backend-kubeapiserver-egress + namespace: {{ .Release.Namespace }} +spec: + endpointSelector: + matchLabels: + {{- include "loki.backendSelectorLabels" . | nindent 6 }} + egress: + - toEntities: + - kube-apiserver +{{- end }} + +{{- end }} + +{{- if and .Values.networkPolicy.discovery.port (eq .Values.networkPolicy.flavor "cilium") }} +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-discovery + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + egress: + - toPorts: + - ports: + - port: "{{ .Values.networkPolicy.discovery.port }}" + protocol: TCP + {{- if .Values.networkPolicy.discovery.namespaceSelector }} + toEndpoints: + - matchLabels: + {{- toYaml .Values.networkPolicy.discovery.namespaceSelector | nindent 8 }} + {{- if .Values.networkPolicy.discovery.podSelector }} + {{- toYaml .Values.networkPolicy.discovery.podSelector | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/compactor/_helpers-compactor.tpl b/charts/loki/templates/compactor/_helpers-compactor.tpl new file mode 100644 index 0000000..75c21db --- /dev/null +++ b/charts/loki/templates/compactor/_helpers-compactor.tpl @@ -0,0 +1,81 @@ +{{/* +compactor fullname +*/}} +{{- define "loki.compactorFullname" -}} +{{ include "loki.fullname" . }}-compactor +{{- end }} + +{{/* +compactor common labels +*/}} +{{- define "loki.compactorLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: compactor +{{- end }} + +{{/* +compactor selector labels +*/}} +{{- define "loki.compactorSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: compactor +{{- end }} + +{{/* +compactor image +*/}} +{{- define "loki.compactorImage" -}} +{{- $dict := dict "loki" .Values.loki.image "service" .Values.compactor.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}} +{{- include "loki.lokiImage" $dict -}} +{{- end }} + +{{/* +compactor readinessProbe +*/}} +{{- define "loki.compactor.readinessProbe" -}} +{{- with .Values.compactor.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +compactor livenessProbe +*/}} +{{- define "loki.compactor.livenessProbe" -}} +{{- with .Values.compactor.livenessProbe }} +livenessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.livenessProbe }} +livenessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +compactor priority class name +*/}} +{{- define "loki.compactorPriorityClassName" }} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.compactor.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} + +{{/* +Create the name of the compactor service account +*/}} +{{- define "loki.compactorServiceAccountName" -}} +{{- if .Values.compactor.serviceAccount.create -}} + {{ default (print (include "loki.serviceAccountName" .) "-compactor") .Values.compactor.serviceAccount.name }} +{{- else -}} + {{ default (include "loki.serviceAccountName" .) .Values.compactor.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/compactor/service-compactor.yaml b/charts/loki/templates/compactor/service-compactor.yaml new file mode 100644 index 0000000..f118b6c --- /dev/null +++ b/charts/loki/templates/compactor/service-compactor.yaml @@ -0,0 +1,38 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.compactorFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} + {{- with .Values.compactor.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + app.kubernetes.io/component: compactor + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.compactor.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.compactor.appProtocol.grpc }} + appProtocol: {{ .Values.compactor.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: compactor +{{- end }} diff --git a/charts/loki/templates/compactor/statefulset-compactor.yaml b/charts/loki/templates/compactor/statefulset-compactor.yaml new file mode 100644 index 0000000..b0a4969 --- /dev/null +++ b/charts/loki/templates/compactor/statefulset-compactor.yaml @@ -0,0 +1,192 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.compactorFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.compactorLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.compactor.replicas }} + podManagementPolicy: Parallel + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.compactorFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.compactor.persistence.enableStatefulSetAutoDeletePVC) }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.compactor.persistence.whenDeleted }} + whenScaled: {{ .Values.compactor.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.compactorSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.compactor.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.compactorLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.compactor.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.compactor.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.compactor.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.compactorPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.compactor.terminationGracePeriodSeconds }} + {{- with .Values.compactor.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: compactor + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.compactor.command }} + command: + - {{ coalesce .Values.compactor.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=compactor + {{- with (concat .Values.global.extraArgs .Values.compactor.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.compactor.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.compactor.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.compactor.readinessProbe" . | nindent 10 }} + {{- include "loki.compactor.livenessProbe" . | nindent 10 }} + volumeMounts: + - name: temp + mountPath: /tmp + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.compactor.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.compactor.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.compactor.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.compactor.extraContainers }} + {{- toYaml .Values.compactor.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.compactor.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.compactor.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.compactor.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: temp + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- if not .Values.compactor.persistence.enabled }} + - name: data + emptyDir: {} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.compactor.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.compactor.persistence.enabled }} + volumeClaimTemplates: + {{- range .Values.compactor.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/config.yaml b/charts/loki/templates/config.yaml new file mode 100644 index 0000000..fe47590 --- /dev/null +++ b/charts/loki/templates/config.yaml @@ -0,0 +1,21 @@ +{{- if .Values.loki.generatedConfigObjectName -}} +apiVersion: v1 +{{- if eq .Values.loki.configStorageType "Secret" }} +kind: Secret +{{- else }} +kind: ConfigMap +{{- end }} +metadata: + name: {{ tpl .Values.loki.generatedConfigObjectName . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +{{- if eq .Values.loki.configStorageType "Secret" }} +data: + config.yaml: {{ include "loki.calculatedConfig" . | b64enc }} +{{- else }} +data: + config.yaml: | + {{ include "loki.calculatedConfig" . | nindent 4 }} +{{- end -}} +{{- end }} diff --git a/charts/loki/templates/distributor/_helpers-distributor.tpl b/charts/loki/templates/distributor/_helpers-distributor.tpl new file mode 100644 index 0000000..c23179e --- /dev/null +++ b/charts/loki/templates/distributor/_helpers-distributor.tpl @@ -0,0 +1,32 @@ +{{/* +distributor fullname +*/}} +{{- define "loki.distributorFullname" -}} +{{ include "loki.fullname" . }}-distributor +{{- end }} + +{{/* +distributor common labels +*/}} +{{- define "loki.distributorLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: distributor +{{- end }} + +{{/* +distributor selector labels +*/}} +{{- define "loki.distributorSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: distributor +{{- end }} + +{{/* +distributor priority class name +*/}} +{{- define "loki.distributorPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.distributor.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/distributor/deployment-distributor.yaml b/charts/loki/templates/distributor/deployment-distributor.yaml new file mode 100644 index 0000000..8b6d6c9 --- /dev/null +++ b/charts/loki/templates/distributor/deployment-distributor.yaml @@ -0,0 +1,155 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.distributorFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.distributorLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.distributor.autoscaling.enabled }} + replicas: {{ .Values.distributor.replicas }} +{{- end }} + strategy: + rollingUpdate: + maxSurge: {{ .Values.distributor.maxSurge }} + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.distributorSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.distributor.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.distributorLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.distributor.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.distributor.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.distributor.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.distributorPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.distributor.terminationGracePeriodSeconds }} + containers: + - name: distributor + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.distributor.command }} + command: + - {{ coalesce .Values.distributor.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=distributor + {{- if .Values.ingester.zoneAwareReplication.enabled }} + {{- if and (.Values.ingester.zoneAwareReplication.migration.enabled) (not .Values.ingester.zoneAwareReplication.migration.writePath) }} + - -distributor.zone-awareness-enabled=false + {{- else }} + - -distributor.zone-awareness-enabled=true + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraArgs .Values.distributor.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.distributor.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.distributor.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + livenessProbe: + {{- toYaml .Values.loki.livenessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.distributor.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.distributor.resources | nindent 12 }} + {{- if .Values.distributor.extraContainers }} + {{- toYaml .Values.distributor.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.distributor.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.distributor.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.distributor.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.distributor.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end -}} diff --git a/charts/loki/templates/distributor/hpa.yaml b/charts/loki/templates/distributor/hpa.yaml new file mode 100644 index 0000000..838a310 --- /dev/null +++ b/charts/loki/templates/distributor/hpa.yaml @@ -0,0 +1,54 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.distributor.autoscaling.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.distributorFullname" . }} + labels: + {{- include "loki.distributorLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "loki.distributorFullname" . }} + minReplicas: {{ .Values.distributor.autoscaling.minReplicas }} + maxReplicas: {{ .Values.distributor.autoscaling.maxReplicas }} + metrics: + {{- with .Values.distributor.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.distributor.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.distributor.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.distributor.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.distributor.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.distributor.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/distributor/poddisruptionbudget-distributor.yaml b/charts/loki/templates/distributor/poddisruptionbudget-distributor.yaml new file mode 100644 index 0000000..806a447 --- /dev/null +++ b/charts/loki/templates/distributor/poddisruptionbudget-distributor.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.distributor.replicas) 1) }} +{{- if kindIs "invalid" .Values.distributor.maxUnavailable }} +{{- fail "`.Values.distributor.maxUnavailable` must be set when `.Values.distributor.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.distributorFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.distributorLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.distributorSelectorLabels" . | nindent 6 }} + {{- with .Values.distributor.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/distributor/service-distributor-headless.yaml b/charts/loki/templates/distributor/service-distributor-headless.yaml new file mode 100644 index 0000000..650b629 --- /dev/null +++ b/charts/loki/templates/distributor/service-distributor-headless.yaml @@ -0,0 +1,39 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.distributorFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.distributorSelectorLabels" . | nindent 4 }} + {{- with .Values.distributor.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + variant: headless + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.distributor.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.distributor.appProtocol.grpc }} + appProtocol: {{ .Values.distributor.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.distributorSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/templates/distributor/service-distributor.yaml b/charts/loki/templates/distributor/service-distributor.yaml new file mode 100644 index 0000000..6a89956 --- /dev/null +++ b/charts/loki/templates/distributor/service-distributor.yaml @@ -0,0 +1,36 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.distributorFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.distributorLabels" . | nindent 4 }} + {{- with .Values.distributor.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.distributor.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.distributor.appProtocol.grpc }} + appProtocol: {{ .Values.distributor.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.distributorSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/templates/extra-manifests.yaml b/charts/loki/templates/extra-manifests.yaml new file mode 100644 index 0000000..7b69423 --- /dev/null +++ b/charts/loki/templates/extra-manifests.yaml @@ -0,0 +1,8 @@ +{{- range .Values.extraObjects }} +--- +{{- if kindIs "map" . }} +{{ tpl (toYaml .) $ }} +{{- else }} +{{ tpl . $ }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/gateway/_helpers-gateway.tpl b/charts/loki/templates/gateway/_helpers-gateway.tpl new file mode 100644 index 0000000..39890b1 --- /dev/null +++ b/charts/loki/templates/gateway/_helpers-gateway.tpl @@ -0,0 +1,47 @@ +{{/* +gateway fullname +*/}} +{{- define "loki.gatewayFullname" -}} +{{ include "loki.fullname" . }}-gateway +{{- end }} + +{{/* +gateway common labels +*/}} +{{- define "loki.gatewayLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: gateway +{{- end }} + +{{/* +gateway selector labels +*/}} +{{- define "loki.gatewaySelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: gateway +{{- end }} + +{{/* +gateway auth secret name +*/}} +{{- define "loki.gatewayAuthSecret" -}} +{{ .Values.gateway.basicAuth.existingSecret | default (include "loki.gatewayFullname" . ) }} +{{- end }} + +{{/* +gateway Docker image +*/}} +{{- define "loki.gatewayImage" -}} +{{- $dict := dict "service" .Values.gateway.image "global" .Values.global.image -}} +{{- include "loki.baseImage" $dict -}} +{{- end }} + +{{/* +gateway priority class name +*/}} +{{- define "loki.gatewayPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.gateway.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/gateway/configmap-gateway.yaml b/charts/loki/templates/gateway/configmap-gateway.yaml new file mode 100644 index 0000000..1c981a7 --- /dev/null +++ b/charts/loki/templates/gateway/configmap-gateway.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.gateway.enabled (not (and .Values.enterprise.enabled .Values.enterprise.gelGateway)) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "loki.gatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} +data: + nginx.conf: | + {{- tpl .Values.gateway.nginxConfig.file . | indent 2 }} +{{- end }} diff --git a/charts/loki/templates/gateway/deployment-gateway-enterprise.yaml b/charts/loki/templates/gateway/deployment-gateway-enterprise.yaml new file mode 100644 index 0000000..6e9bb15 --- /dev/null +++ b/charts/loki/templates/gateway/deployment-gateway-enterprise.yaml @@ -0,0 +1,152 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and .Values.gateway.enabled .Values.enterprise.enabled .Values.enterprise.gelGateway }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "loki.gatewayFullname" . }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} + {{- with .Values.enterpriseGateway.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterpriseGateway.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.enterpriseGateway.replicas }} + selector: + matchLabels: + {{- include "loki.gatewaySelectorLabels" . | nindent 6 }} + strategy: + {{- toYaml .Values.enterpriseGateway.strategy | nindent 4 }} + template: + metadata: + labels: + {{- include "loki.gatewaySelectorLabels" . | nindent 8 }} + {{- with .Values.enterpriseGateway.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{- if .Values.useExternalConfig }} + checksum/config: {{ .Values.externalConfigVersion }} + {{- else }} + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- end}} + {{- with .Values.enterpriseGateway.annotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.enterpriseGateway.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ template "loki.serviceAccountName" . }} + {{- if .Values.enterpriseGateway.priorityClassName }} + priorityClassName: {{ .Values.enterpriseGateway.priorityClassName }} + {{- end }} + securityContext: + {{- toYaml .Values.enterpriseGateway.podSecurityContext | nindent 8 }} + initContainers: + {{- toYaml .Values.enterpriseGateway.initContainers | nindent 8 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.enterpriseGateway.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: gateway + image: "{{ template "loki.image" . }}" + imagePullPolicy: {{ .Values.enterprise.image.pullPolicy }} + args: + - -target=gateway + - -config.file=/etc/loki/config/config.yaml + {{- if .Values.minio.enabled }} + - -admin.client.backend-type=s3 + - -admin.client.s3.endpoint={{ template "loki.minio" . }} + - -admin.client.s3.bucket-name={{ .Values.loki.storage.bucketNames.admin }} + - -admin.client.s3.access-key-id={{ (index .Values.minio.users 0).accessKey }} + - -admin.client.s3.secret-access-key={{ (index .Values.minio.users 0).secretKey }} + - -admin.client.s3.insecure={{ .Values.loki.storage.s3.insecure }} + {{- end }} + {{- if and $isDistributed .Values.enterpriseGateway.useDefaultProxyURLs }} + - -gateway.proxy.default.url=http://{{ template "loki.fullname" . }}-admin-api.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.admin-api.url=http://{{ template "loki.fullname" . }}-admin-api.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.distributor.url=dns:///{{ template "loki.fullname" . }}-distributor-headless.{{ .Release.Namespace }}.svc:9095 + - -gateway.proxy.ingester.url=http://{{ template "loki.fullname" . }}-ingester.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.query-frontend.url=http://{{ template "loki.fullname" . }}-query-frontend.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.ruler.url=http://{{ template "loki.fullname" . }}-ruler.{{ .Release.Namespace }}.svc:3100 + {{- end }} + {{- if and $isSimpleScalable .Values.enterpriseGateway.useDefaultProxyURLs }} + - -gateway.proxy.default.url=http://{{ template "enterprise-logs.adminApiFullname" . }}.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.admin-api.url=http://{{ template "enterprise-logs.adminApiFullname" . }}.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.compactor.url=http://{{ template "loki.backendFullname" . }}-headless.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.distributor.url=dns:///{{ template "loki.writeFullname" . }}-headless.{{ .Release.Namespace }}.svc:9095 + - -gateway.proxy.ingester.url=http://{{ template "loki.writeFullname" . }}.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.query-frontend.url=http://{{ template "loki.readFullname" . }}.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.ruler.url=http://{{ template "loki.backendFullname" . }}-headless.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.query-scheduler.url=http://{{ template "loki.backendFullname" . }}-headless.{{ .Release.Namespace }}.svc:3100 + {{- end }} + {{- range $key, $value := .Values.enterpriseGateway.extraArgs }} + - "-{{ $key }}={{ $value }}" + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: license + mountPath: /etc/loki/license + - name: storage + mountPath: /data + {{- if .Values.enterpriseGateway.extraVolumeMounts }} + {{ toYaml .Values.enterpriseGateway.extraVolumeMounts | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + readinessProbe: + {{- toYaml .Values.enterpriseGateway.readinessProbe | nindent 12 }} + resources: + {{- toYaml .Values.enterpriseGateway.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.enterpriseGateway.containerSecurityContext | nindent 12 }} + env: + {{- if .Values.enterpriseGateway.env }} + {{ toYaml .Values.enterpriseGateway.env | nindent 12 }} + {{- end }} + {{- with .Values.enterpriseGateway.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.enterpriseGateway.extraContainers }} + {{ toYaml . | nindent 8 }} + {{- end }} + nodeSelector: + {{- toYaml .Values.enterpriseGateway.nodeSelector | nindent 8 }} + affinity: + {{- toYaml .Values.enterpriseGateway.affinity | nindent 8 }} + tolerations: + {{- toYaml .Values.enterpriseGateway.tolerations | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.enterpriseGateway.terminationGracePeriodSeconds }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + - name: storage + emptyDir: {} + {{- if .Values.enterpriseGateway.extraVolumes }} + {{ toYaml .Values.enterpriseGateway.extraVolumes | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/gateway/deployment-gateway-nginx.yaml b/charts/loki/templates/gateway/deployment-gateway-nginx.yaml new file mode 100644 index 0000000..94562ad --- /dev/null +++ b/charts/loki/templates/gateway/deployment-gateway-nginx.yaml @@ -0,0 +1,138 @@ +{{- if and .Values.gateway.enabled (not (and .Values.enterprise.enabled .Values.enterprise.gelGateway)) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.gatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} + {{- if or (not (empty .Values.loki.annotations)) (not (empty .Values.backend.annotations))}} + annotations: + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.gateway.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: +{{- if not .Values.gateway.autoscaling.enabled }} + replicas: {{ .Values.gateway.replicas }} +{{- end }} +{{- with .Values.gateway.deploymentStrategy }} + strategy: +{{ toYaml . | trim | indent 4 }} +{{- end }} + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.gatewaySelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/gateway/configmap-gateway.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.gateway.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- with .Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.gateway.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.gatewaySelectorLabels" . | nindent 8 }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{ include "loki.enableServiceLinks" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end -}} + {{- include "loki.gatewayPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.gateway.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.gateway.terminationGracePeriodSeconds }} + containers: + - name: nginx + image: {{ include "loki.gatewayImage" . }} + imagePullPolicy: {{ .Values.gateway.image.pullPolicy }} + ports: + - name: http-metrics + containerPort: {{ .Values.gateway.containerPort }} + protocol: TCP + {{- with .Values.gateway.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.gateway.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + readinessProbe: + {{- toYaml .Values.gateway.readinessProbe | nindent 12 }} + securityContext: + {{- toYaml .Values.gateway.containerSecurityContext | nindent 12 }} + {{- with .Values.gateway.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/nginx + {{- if .Values.gateway.basicAuth.enabled }} + - name: auth + mountPath: /etc/nginx/secrets + {{- end }} + - name: tmp + mountPath: /tmp + - name: docker-entrypoint-d-override + mountPath: /docker-entrypoint.d + {{- if .Values.gateway.extraVolumeMounts }} + {{- toYaml .Values.gateway.extraVolumeMounts | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.gateway.resources | nindent 12 }} + {{- if .Values.gateway.extraContainers }} + {{- toYaml .Values.gateway.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.gateway.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.gateway.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.gateway.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.gateway.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.gateway.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "loki.gatewayFullname" . }} + {{- if .Values.gateway.basicAuth.enabled }} + - name: auth + secret: + secretName: {{ include "loki.gatewayAuthSecret" . }} + {{- end }} + - name: tmp + emptyDir: {} + - name: docker-entrypoint-d-override + emptyDir: {} + {{- if .Values.gateway.extraVolumes }} + {{- toYaml .Values.gateway.extraVolumes | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/gateway/hpa.yaml b/charts/loki/templates/gateway/hpa.yaml new file mode 100644 index 0000000..3541ec6 --- /dev/null +++ b/charts/loki/templates/gateway/hpa.yaml @@ -0,0 +1,50 @@ +{{- $autoscalingv2 := .Capabilities.APIVersions.Has "autoscaling/v2" -}} +{{- if .Values.gateway.autoscaling.enabled }} +{{- if $autoscalingv2 }} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta1 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.gatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "loki.gatewayFullname" . }} + minReplicas: {{ .Values.gateway.autoscaling.minReplicas }} + maxReplicas: {{ .Values.gateway.autoscaling.maxReplicas }} + {{- with .Values.gateway.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} + metrics: + {{- with .Values.gateway.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.gateway.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/gateway/ingress-gateway.yaml b/charts/loki/templates/gateway/ingress-gateway.yaml new file mode 100644 index 0000000..6f18e33 --- /dev/null +++ b/charts/loki/templates/gateway/ingress-gateway.yaml @@ -0,0 +1,59 @@ +{{- if and .Values.gateway.enabled -}} +{{- if .Values.gateway.ingress.enabled -}} +{{- $ingressApiIsStable := eq (include "loki.ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "loki.ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "loki.ingress.supportsPathType" .) "true" -}} +apiVersion: {{ include "loki.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ include "loki.gatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} + {{- range $labelKey, $labelValue := .Values.gateway.ingress.labels }} + {{ $labelKey }}: {{ $labelValue | toYaml }} + {{- end }} + {{- with .Values.gateway.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.gateway.ingress.ingressClassName }} + ingressClassName: {{ .Values.gateway.ingress.ingressClassName }} + {{- end -}} + {{- if .Values.gateway.ingress.tls }} + tls: + {{- range .Values.gateway.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ tpl . $ | quote }} + {{- end }} + {{- with .secretName }} + secretName: {{ . }} + {{- end }} + {{- end }} + {{- end }} + rules: + {{- range .Values.gateway.ingress.hosts }} + - host: {{ tpl .host $ | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if $ingressSupportsPathType }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ include "loki.gatewayFullname" $ }} + port: + number: {{ $.Values.gateway.service.port }} + {{- else }} + serviceName: {{ include "loki.gatewayFullname" $ }} + servicePort: {{ $.Values.gateway.service.port }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/gateway/poddisruptionbudget-gateway.yaml b/charts/loki/templates/gateway/poddisruptionbudget-gateway.yaml new file mode 100644 index 0000000..0057c56 --- /dev/null +++ b/charts/loki/templates/gateway/poddisruptionbudget-gateway.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.gateway.enabled }} +{{- if or + (and (not .Values.gateway.autoscaling.enabled) (gt (int .Values.gateway.replicas) 1)) + (and .Values.gateway.autoscaling.enabled (gt (int .Values.gateway.autoscaling.minReplicas) 1)) +}} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.gatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.gatewaySelectorLabels" . | nindent 6 }} + maxUnavailable: 1 +{{- end }} +{{- end }} diff --git a/charts/loki/templates/gateway/secret-gateway.yaml b/charts/loki/templates/gateway/secret-gateway.yaml new file mode 100644 index 0000000..c3c5e9a --- /dev/null +++ b/charts/loki/templates/gateway/secret-gateway.yaml @@ -0,0 +1,14 @@ +{{- with .Values.gateway }} +{{- if and .enabled .basicAuth.enabled (not .basicAuth.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "loki.gatewayFullname" $ }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" $ | nindent 4 }} +stringData: + .htpasswd: | + {{- tpl .basicAuth.htpasswd $ | nindent 4 }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/gateway/service-gateway.yaml b/charts/loki/templates/gateway/service-gateway.yaml new file mode 100644 index 0000000..af44d0e --- /dev/null +++ b/charts/loki/templates/gateway/service-gateway.yaml @@ -0,0 +1,43 @@ +{{- if .Values.gateway.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.gatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.gateway.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if not (and .Values.enterprise.enabled .Values.enterprise.gelGateway) }} + prometheus.io/service-monitor: "false" + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.gateway.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: {{ .Values.gateway.service.type }} + {{- with .Values.gateway.service.clusterIP }} + clusterIP: {{ . }} + {{- end }} + {{- if and (eq "LoadBalancer" .Values.gateway.service.type) .Values.gateway.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.gateway.service.loadBalancerIP }} + {{- end }} + ports: + - name: http-metrics + port: {{ .Values.gateway.service.port }} + targetPort: http-metrics + {{- if and (eq "NodePort" .Values.gateway.service.type) .Values.gateway.service.nodePort }} + nodePort: {{ .Values.gateway.service.nodePort }} + {{- end }} + protocol: TCP + selector: + {{- include "loki.gatewaySelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/index-gateway/_helpers-index-gateway.tpl b/charts/loki/templates/index-gateway/_helpers-index-gateway.tpl new file mode 100644 index 0000000..f42dff3 --- /dev/null +++ b/charts/loki/templates/index-gateway/_helpers-index-gateway.tpl @@ -0,0 +1,40 @@ +{{/* +index-gateway fullname +*/}} +{{- define "loki.indexGatewayFullname" -}} +{{ include "loki.fullname" . }}-index-gateway +{{- end }} + +{{/* +index-gateway common labels +*/}} +{{- define "loki.indexGatewayLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: index-gateway +{{- end }} + +{{/* +index-gateway selector labels +*/}} +{{- define "loki.indexGatewaySelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: index-gateway +{{- end }} + +{{/* +index-gateway image +*/}} +{{- define "loki.indexGatewayImage" -}} +{{- $dict := dict "loki" .Values.loki.image "service" .Values.indexGateway.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}} +{{- include "loki.lokiImage" $dict -}} +{{- end }} + +{{/* +index-gateway priority class name +*/}} +{{- define "loki.indexGatewayPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.indexGateway.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/index-gateway/poddisruptionbudget-index-gateway.yaml b/charts/loki/templates/index-gateway/poddisruptionbudget-index-gateway.yaml new file mode 100644 index 0000000..cc230c2 --- /dev/null +++ b/charts/loki/templates/index-gateway/poddisruptionbudget-index-gateway.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.indexGateway.replicas) 1) }} +{{- if kindIs "invalid" .Values.indexGateway.maxUnavailable }} +{{- fail "`.Values.indexGateway.maxUnavailable` must be set when `.Values.indexGateway.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.indexGatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.indexGatewayLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.indexGatewaySelectorLabels" . | nindent 6 }} + {{- with .Values.indexGateway.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/index-gateway/service-index-gateway-headless.yaml b/charts/loki/templates/index-gateway/service-index-gateway-headless.yaml new file mode 100644 index 0000000..731a984 --- /dev/null +++ b/charts/loki/templates/index-gateway/service-index-gateway-headless.yaml @@ -0,0 +1,35 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.indexGatewayFullname" . }}-headless + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.indexGatewaySelectorLabels" . | nindent 4 }} + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.indexGateway.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- with .Values.indexGateway.appProtocol.grpc }} + appProtocol: {{ . }} + {{- end }} + selector: + {{- include "loki.indexGatewaySelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/index-gateway/service-index-gateway.yaml b/charts/loki/templates/index-gateway/service-index-gateway.yaml new file mode 100644 index 0000000..b1a3523 --- /dev/null +++ b/charts/loki/templates/index-gateway/service-index-gateway.yaml @@ -0,0 +1,36 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.indexGatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.indexGatewayLabels" . | nindent 4 }} + {{- with .Values.indexGateway.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.indexGateway.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- with .Values.indexGateway.appProtocol.grpc }} + appProtocol: {{ . }} + {{- end }} + selector: + {{- include "loki.indexGatewaySelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/index-gateway/statefulset-index-gateway.yaml b/charts/loki/templates/index-gateway/statefulset-index-gateway.yaml new file mode 100644 index 0000000..0a725e9 --- /dev/null +++ b/charts/loki/templates/index-gateway/statefulset-index-gateway.yaml @@ -0,0 +1,191 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.indexGatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.indexGatewayLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.indexGateway.replicas }} +{{- with .Values.indexGateway.updateStrategy }} + updateStrategy: + {{- tpl (. | toYaml) $ | nindent 4 }} +{{- end }} + serviceName: {{ include "loki.indexGatewayFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.indexGateway.persistence.enableStatefulSetAutoDeletePVC) }} + {{/* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.indexGateway.persistence.whenDeleted }} + whenScaled: {{ .Values.indexGateway.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.indexGatewaySelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.indexGateway.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.indexGatewayLabels" . | nindent 8 }} + {{- with merge (dict) .Values.loki.podLabels .Values.indexGateway.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.indexGateway.joinMemberlist }} + app.kubernetes.io/part-of: memberlist + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.indexGateway.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.indexGatewayPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.indexGateway.terminationGracePeriodSeconds }} + {{- with .Values.indexGateway.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: index-gateway + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=index-gateway + {{- with (concat .Values.global.extraArgs .Values.indexGateway.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + {{- if .Values.indexGateway.joinMemberlist }} + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- end }} + {{- with (concat .Values.global.extraEnv .Values.indexGateway.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.indexGateway.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + livenessProbe: + {{- toYaml .Values.loki.livenessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.indexGateway.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.indexGateway.resources | nindent 12 }} + {{- if .Values.indexGateway.extraContainers }} + {{- toYaml .Values.indexGateway.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.indexGateway.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.indexGateway.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.indexGateway.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.indexGateway.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.indexGateway.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.indexGateway.persistence.enabled }} + - name: data + emptyDir: {} + {{- else if .Values.indexGateway.persistence.inMemory }} + - name: data + {{- if .Values.indexGateway.persistence.inMemory }} + emptyDir: + medium: Memory + {{- end }} + {{- if .Values.indexGateway.persistence.size }} + sizeLimit: {{ .Values.indexGateway.persistence.size }} + {{- end }} + {{- else }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + {{- with .Values.indexGateway.persistence.annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.indexGateway.persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .Values.indexGateway.persistence.size | quote }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/ingester/_helpers-ingester.tpl b/charts/loki/templates/ingester/_helpers-ingester.tpl new file mode 100644 index 0000000..70728a0 --- /dev/null +++ b/charts/loki/templates/ingester/_helpers-ingester.tpl @@ -0,0 +1,92 @@ +{{/* +ingester fullname +*/}} +{{- define "loki.ingesterFullname" -}} +{{ include "loki.fullname" . }}-ingester +{{- end }} + +{{/* +ingester common labels +*/}} +{{- define "loki.ingesterLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: ingester +{{- end }} + +{{/* +ingester selector labels +*/}} +{{- define "loki.ingesterSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: ingester +{{- end }} + +{{/* +ingester priority class name +*/}} +{{- define "loki.ingesterPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.ingester.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} + +{{- define "loki.ingester.readinessProbe" -}} +{{- with .Values.ingester.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{- define "loki.ingester.livenessProbe" -}} +{{- with .Values.ingester.livenessProbe }} +livenessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.livenessProbe }} +livenessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +expects global context +*/}} +{{- define "loki.ingester.replicaCount" -}} +{{- ceil (divf .Values.ingester.replicas 3) -}} +{{- end -}} + +{{/* +expects a dict +{ + "replicas": replicas in a zone, + "ctx": global context +} +*/}} +{{- define "loki.ingester.maxUnavailable" -}} +{{- ceil (mulf .replicas (divf (int .ctx.Values.ingester.zoneAwareReplication.maxUnavailablePct) 100)) -}} +{{- end -}} + +{{/* +Return rollout-group prefix if it is set +*/}} +{{- define "loki.prefixRolloutGroup" -}} +{{- if .Values.ingester.rolloutGroupPrefix -}} +{{- .Values.ingester.rolloutGroupPrefix -}}- +{{- end -}} +{{- end -}} + +{{/* +Return ingester name prefix if required +*/}} +{{- define "loki.prefixIngesterName" -}} +{{- if .Values.ingester.addIngesterNamePrefix -}} +loki- +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/ingester/hpa-zone-a.yaml b/charts/loki/templates/ingester/hpa-zone-a.yaml new file mode 100644 index 0000000..5ede187 --- /dev/null +++ b/charts/loki/templates/ingester/hpa-zone-a.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.autoscaling.enabled .Values.ingester.zoneAwareReplication.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-a + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.ingesterFullname" . }}-zone-a + minReplicas: {{ .Values.ingester.autoscaling.minReplicas }} + maxReplicas: {{ .Values.ingester.autoscaling.maxReplicas }} + metrics: + {{- with .Values.ingester.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingester.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.ingester.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.ingester.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/ingester/hpa-zone-b.yaml b/charts/loki/templates/ingester/hpa-zone-b.yaml new file mode 100644 index 0000000..b001a6a --- /dev/null +++ b/charts/loki/templates/ingester/hpa-zone-b.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.autoscaling.enabled .Values.ingester.zoneAwareReplication.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-b + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.ingesterFullname" . }}-zone-b + minReplicas: {{ .Values.ingester.autoscaling.minReplicas }} + maxReplicas: {{ .Values.ingester.autoscaling.maxReplicas }} + metrics: + {{- with .Values.ingester.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingester.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.ingester.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.ingester.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/ingester/hpa-zone-c.yaml b/charts/loki/templates/ingester/hpa-zone-c.yaml new file mode 100644 index 0000000..82f229c --- /dev/null +++ b/charts/loki/templates/ingester/hpa-zone-c.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.autoscaling.enabled .Values.ingester.zoneAwareReplication.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-c + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.ingesterFullname" . }}-zone-c + minReplicas: {{ .Values.ingester.autoscaling.minReplicas }} + maxReplicas: {{ .Values.ingester.autoscaling.maxReplicas }} + metrics: + {{- with .Values.ingester.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingester.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.ingester.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.ingester.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/ingester/hpa.yaml b/charts/loki/templates/ingester/hpa.yaml new file mode 100644 index 0000000..de35d67 --- /dev/null +++ b/charts/loki/templates/ingester/hpa.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.autoscaling.enabled (or (not .Values.ingester.zoneAwareReplication.enabled) .Values.ingester.zoneAwareReplication.migration.enabled) }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.ingesterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.ingesterFullname" . }} + minReplicas: {{ .Values.ingester.autoscaling.minReplicas }} + maxReplicas: {{ .Values.ingester.autoscaling.maxReplicas }} + metrics: + {{- with .Values.ingester.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingester.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.ingester.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.ingester.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/ingester/poddisruptionbudget-ingester-rollout.yaml b/charts/loki/templates/ingester/poddisruptionbudget-ingester-rollout.yaml new file mode 100644 index 0000000..4c1b133 --- /dev/null +++ b/charts/loki/templates/ingester/poddisruptionbudget-ingester-rollout.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.ingester.replicas) 1) (.Values.ingester.zoneAwareReplication.enabled) }} +{{- if kindIs "invalid" .Values.ingester.maxUnavailable }} +{{- fail "`.Values.ingester.maxUnavailable` must be set when `.Values.ingester.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.ingesterFullname" . }}-rollout + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + {{- with .Values.ingester.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/ingester/poddisruptionbudget-ingester.yaml b/charts/loki/templates/ingester/poddisruptionbudget-ingester.yaml new file mode 100644 index 0000000..f5c4838 --- /dev/null +++ b/charts/loki/templates/ingester/poddisruptionbudget-ingester.yaml @@ -0,0 +1,27 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.ingester.replicas) 1) (or (not .Values.ingester.zoneAwareReplication.enabled) .Values.ingester.zoneAwareReplication.migration.enabled) }} +{{- if kindIs "invalid" .Values.ingester.maxUnavailable }} +{{- fail "`.Values.ingester.maxUnavailable` must be set when `.Values.ingester.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.ingesterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.ingesterSelectorLabels" . | nindent 6 }} + {{/* zone aware ingesters get their own pod disruption budget, ignore them here */}} + matchExpressions: + - key: rollout-group + operator: NotIn + values: + - '{{ include "loki.prefixRolloutGroup" . }}ingester' + {{- with .Values.ingester.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/ingester/service-ingester-headless.yaml b/charts/loki/templates/ingester/service-ingester-headless.yaml new file mode 100644 index 0000000..8a8b92f --- /dev/null +++ b/charts/loki/templates/ingester/service-ingester-headless.yaml @@ -0,0 +1,35 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (or (not .Values.ingester.zoneAwareReplication.enabled) .Values.ingester.zoneAwareReplication.migration.enabled) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.ingesterFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterSelectorLabels" . | nindent 4 }} + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.ingester.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.ingester.appProtocol.grpc }} + appProtocol: {{ .Values.ingester.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.ingesterSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/templates/ingester/service-ingester-zone-a-headless.yaml b/charts/loki/templates/ingester/service-ingester-zone-a-headless.yaml new file mode 100644 index 0000000..380ed09 --- /dev/null +++ b/charts/loki/templates/ingester/service-ingester-zone-a-headless.yaml @@ -0,0 +1,38 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.zoneAwareReplication.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-a-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + {{- with .Values.ingester.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.ingester.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.ingester.appProtocol.grpc }} + appProtocol: {{ .Values.ingester.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.ingesterSelectorLabels" . | nindent 4 }} + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-a + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester +{{- end -}} diff --git a/charts/loki/templates/ingester/service-ingester-zone-b-headless.yaml b/charts/loki/templates/ingester/service-ingester-zone-b-headless.yaml new file mode 100644 index 0000000..00d851f --- /dev/null +++ b/charts/loki/templates/ingester/service-ingester-zone-b-headless.yaml @@ -0,0 +1,38 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.zoneAwareReplication.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-b-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + {{- with .Values.ingester.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.ingester.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.ingester.appProtocol.grpc }} + appProtocol: {{ .Values.ingester.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.ingesterSelectorLabels" . | nindent 4 }} + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-b + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester +{{- end -}} diff --git a/charts/loki/templates/ingester/service-ingester-zone-c-headless.yaml b/charts/loki/templates/ingester/service-ingester-zone-c-headless.yaml new file mode 100644 index 0000000..0bacdbc --- /dev/null +++ b/charts/loki/templates/ingester/service-ingester-zone-c-headless.yaml @@ -0,0 +1,38 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.zoneAwareReplication.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-c-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + {{- with .Values.ingester.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.ingester.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.ingester.appProtocol.grpc }} + appProtocol: {{ .Values.ingester.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.ingesterSelectorLabels" . | nindent 4 }} + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-c + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester +{{- end -}} diff --git a/charts/loki/templates/ingester/service-ingester.yaml b/charts/loki/templates/ingester/service-ingester.yaml new file mode 100644 index 0000000..94d6f83 --- /dev/null +++ b/charts/loki/templates/ingester/service-ingester.yaml @@ -0,0 +1,36 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (or (not .Values.ingester.zoneAwareReplication.enabled) .Values.ingester.zoneAwareReplication.migration.enabled) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.ingesterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + {{- with .Values.ingester.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.ingester.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.ingester.appProtocol.grpc }} + appProtocol: {{ .Values.ingester.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.ingesterSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/templates/ingester/statefulset-ingester-zone-a.yaml b/charts/loki/templates/ingester/statefulset-ingester-zone-a.yaml new file mode 100644 index 0000000..9b21dec --- /dev/null +++ b/charts/loki/templates/ingester/statefulset-ingester-zone-a.yaml @@ -0,0 +1,233 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.zoneAwareReplication.enabled }} +{{- $replicas := (include "loki.ingester.replicaCount" .) -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-a + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-a + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + annotations: + rollout-max-unavailable: "{{ include "loki.ingester.maxUnavailable" (dict "ctx" . "replicas" $replicas)}}" + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneA.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.ingester.autoscaling.enabled }} + replicas: {{ $replicas }} +{{- end }} + podManagementPolicy: Parallel + serviceName: {{ include "loki.ingesterFullname" . }}-zone-a + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.ingester.persistence.enableStatefulSetAutoDeletePVC) }} + {{/* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.ingester.persistence.whenDeleted }} + whenScaled: {{ .Values.ingester.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.ingesterSelectorLabels" . | nindent 6 }} + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-a + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester +{{- with .Values.ingester.updateStrategy }} + updateStrategy: + {{- tpl (. | toYaml) $ | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneA.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.ingesterLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-a + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + {{- with merge (dict) .Values.loki.podLabels .Values.ingester.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.ingester.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.ingesterPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.ingester.terminationGracePeriodSeconds }} + {{- with .Values.ingester.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: ingester + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.ingester.command }} + command: + - {{ coalesce .Values.ingester.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -ingester.availability-zone=zone-a + - -ingester.unregister-on-shutdown=false + - -ingester.tokens-file-path=/var/loki/ring-tokens + - -target=ingester + {{- with (concat .Values.global.extraArgs .Values.ingester.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.ingester.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.ingester.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.ingester.readinessProbe" . | nindent 10 }} + {{- include "loki.ingester.livenessProbe" . | nindent 10 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.ingester.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.ingester.extraContainers }} + {{- toYaml .Values.ingester.extraContainers | nindent 8}} + {{- end }} + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: rollout-group + operator: In + values: + - {{ include "loki.prefixRolloutGroup" . }}ingester + - key: name + operator: NotIn + values: + - {{ include "loki.prefixIngesterName" . }}ingester-zone-a + topologyKey: kubernetes.io/hostname + {{- with .Values.ingester.zoneAwareReplication.zoneA.extraAffinity }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneA.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.ingester.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.ingester.persistence.enabled }} + - name: data + emptyDir: {} + {{- else if .Values.ingester.persistence.inMemory }} + - name: data + {{- if .Values.ingester.persistence.inMemory }} + emptyDir: + medium: Memory + {{- end }} + {{- if .Values.ingester.persistence.size }} + sizeLimit: {{ .Values.ingester.persistence.size }} + {{- end }} + {{- else }} + volumeClaimTemplates: + {{- range .Values.ingester.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/ingester/statefulset-ingester-zone-b.yaml b/charts/loki/templates/ingester/statefulset-ingester-zone-b.yaml new file mode 100644 index 0000000..0b79c05 --- /dev/null +++ b/charts/loki/templates/ingester/statefulset-ingester-zone-b.yaml @@ -0,0 +1,233 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.zoneAwareReplication.enabled }} +{{- $replicas := (include "loki.ingester.replicaCount" .) -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-b + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-b + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + annotations: + rollout-max-unavailable: "{{ include "loki.ingester.maxUnavailable" (dict "ctx" . "replicas" $replicas)}}" + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneB.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.ingester.autoscaling.enabled }} + replicas: {{ $replicas }} +{{- end }} + podManagementPolicy: Parallel + serviceName: {{ include "loki.ingesterFullname" . }}-zone-b + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.ingester.persistence.enableStatefulSetAutoDeletePVC) }} + {{/* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.ingester.persistence.whenDeleted }} + whenScaled: {{ .Values.ingester.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.ingesterSelectorLabels" . | nindent 6 }} + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-b + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester +{{- with .Values.ingester.updateStrategy }} + updateStrategy: + {{- tpl (. | toYaml) $ | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneB.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.ingesterLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-b + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + {{- with merge (dict) .Values.ingester.podLabels .Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.ingester.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.ingesterPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.ingester.terminationGracePeriodSeconds }} + {{- with .Values.ingester.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: ingester + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.ingester.command }} + command: + - {{ coalesce .Values.ingester.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -ingester.availability-zone=zone-b + - -ingester.unregister-on-shutdown=false + - -ingester.tokens-file-path=/var/loki/ring-tokens + - -target=ingester + {{- with (concat .Values.global.extraArgs .Values.ingester.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.ingester.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.ingester.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.ingester.readinessProbe" . | nindent 10 }} + {{- include "loki.ingester.livenessProbe" . | nindent 10 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.ingester.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.ingester.extraContainers }} + {{- toYaml .Values.ingester.extraContainers | nindent 8}} + {{- end }} + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: rollout-group + operator: In + values: + - {{ include "loki.prefixRolloutGroup" . }}ingester + - key: name + operator: NotIn + values: + - {{ include "loki.prefixIngesterName" . }}ingester-zone-b + topologyKey: kubernetes.io/hostname + {{- with .Values.ingester.zoneAwareReplication.zoneB.extraAffinity }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneB.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.ingester.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.ingester.persistence.enabled }} + - name: data + emptyDir: {} + {{- else if .Values.ingester.persistence.inMemory }} + - name: data + {{- if .Values.ingester.persistence.inMemory }} + emptyDir: + medium: Memory + {{- end }} + {{- if .Values.ingester.persistence.size }} + sizeLimit: {{ .Values.ingester.persistence.size }} + {{- end }} + {{- else }} + volumeClaimTemplates: + {{- range .Values.ingester.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/ingester/statefulset-ingester-zone-c.yaml b/charts/loki/templates/ingester/statefulset-ingester-zone-c.yaml new file mode 100644 index 0000000..140bf7a --- /dev/null +++ b/charts/loki/templates/ingester/statefulset-ingester-zone-c.yaml @@ -0,0 +1,233 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.zoneAwareReplication.enabled }} +{{- $replicas := (include "loki.ingester.replicaCount" .) -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-c + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-c + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + annotations: + rollout-max-unavailable: "{{ include "loki.ingester.maxUnavailable" (dict "ctx" . "replicas" $replicas)}}" + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneC.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.ingester.autoscaling.enabled }} + replicas: {{ $replicas }} +{{- end }} + podManagementPolicy: Parallel + serviceName: {{ include "loki.ingesterFullname" . }}-zone-c + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.ingester.persistence.enableStatefulSetAutoDeletePVC) }} + {{/* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.ingester.persistence.whenDeleted }} + whenScaled: {{ .Values.ingester.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.ingesterSelectorLabels" . | nindent 6 }} + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-c + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester +{{- with .Values.ingester.updateStrategy }} + updateStrategy: + {{- tpl (. | toYaml) $ | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneC.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.ingesterLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-c + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + {{- with merge (dict) .Values.ingester.podLabels .Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.ingester.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.ingesterPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.ingester.terminationGracePeriodSeconds }} + {{- with .Values.ingester.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: ingester + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.ingester.command }} + command: + - {{ coalesce .Values.ingester.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -ingester.availability-zone=zone-c + - -ingester.unregister-on-shutdown=false + - -ingester.tokens-file-path=/var/loki/ring-tokens + - -target=ingester + {{- with (concat .Values.global.extraArgs .Values.ingester.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.ingester.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.ingester.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.ingester.readinessProbe" . | nindent 10 }} + {{- include "loki.ingester.livenessProbe" . | nindent 10 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.ingester.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.ingester.extraContainers }} + {{- toYaml .Values.ingester.extraContainers | nindent 8}} + {{- end }} + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: rollout-group + operator: In + values: + - {{ include "loki.prefixIngesterName" . }}ingester + - key: name + operator: NotIn + values: + - {{ include "loki.prefixIngesterName" . }}ingester-zone-c + topologyKey: kubernetes.io/hostname + {{- with .Values.ingester.zoneAwareReplication.zoneC.extraAffinity }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneC.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.ingester.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.ingester.persistence.enabled }} + - name: data + emptyDir: {} + {{- else if .Values.ingester.persistence.inMemory }} + - name: data + {{- if .Values.ingester.persistence.inMemory }} + emptyDir: + medium: Memory + {{- end }} + {{- if .Values.ingester.persistence.size }} + sizeLimit: {{ .Values.ingester.persistence.size }} + {{- end }} + {{- else }} + volumeClaimTemplates: + {{- range .Values.ingester.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/ingester/statefulset-ingester.yaml b/charts/loki/templates/ingester/statefulset-ingester.yaml new file mode 100644 index 0000000..9055fe2 --- /dev/null +++ b/charts/loki/templates/ingester/statefulset-ingester.yaml @@ -0,0 +1,204 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (or (not .Values.ingester.zoneAwareReplication.enabled) .Values.ingester.zoneAwareReplication.migration.enabled) }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.ingesterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.ingester.autoscaling.enabled }} + replicas: {{ .Values.ingester.replicas }} +{{- end }} + podManagementPolicy: Parallel +{{- with .Values.ingester.updateStrategy }} + updateStrategy: + {{- tpl (. | toYaml) $ | nindent 4 }} +{{- end }} + serviceName: {{ include "loki.ingesterFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.ingester.persistence.enableStatefulSetAutoDeletePVC) }} + {{/* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.ingester.persistence.whenDeleted }} + whenScaled: {{ .Values.ingester.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.ingesterSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.ingesterLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.ingester.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.ingester.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.ingesterPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.ingester.terminationGracePeriodSeconds }} + {{- with .Values.ingester.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: ingester + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.ingester.command }} + command: + - {{ coalesce .Values.ingester.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -ingester.availability-zone=zone-default + - -target=ingester + {{- with (concat .Values.global.extraArgs .Values.ingester.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.ingester.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.ingester.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.ingester.readinessProbe" . | nindent 10 }} + {{- include "loki.ingester.livenessProbe" . | nindent 10 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.ingester.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.ingester.extraContainers }} + {{- toYaml .Values.ingester.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.ingester.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.ingester.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.ingester.persistence.enabled }} + - name: data + emptyDir: { } + {{- else if .Values.ingester.persistence.inMemory }} + - name: data + {{- if .Values.ingester.persistence.inMemory }} + emptyDir: + medium: Memory + {{- end }} + {{- if .Values.ingester.persistence.size }} + sizeLimit: {{ .Values.ingester.persistence.size }} + {{- end }} + {{- else }} + volumeClaimTemplates: + {{- range .Values.ingester.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/ingress.yaml b/charts/loki/templates/ingress.yaml new file mode 100644 index 0000000..ddbcf7f --- /dev/null +++ b/charts/loki/templates/ingress.yaml @@ -0,0 +1,40 @@ +{{- if .Values.ingress.enabled }} +{{- $ingressSupportsIngressClassName := eq (include "loki.ingress.supportsIngressClassName" .) "true" -}} +apiVersion: {{ include "loki.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ include "loki.fullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end -}} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ tpl . $ | quote }} + {{- end }} + {{- with .secretName }} + secretName: {{ . }} + {{- end }} + {{- end }} + {{- end }} + rules: + {{- range $.Values.ingress.hosts }} + - host: {{ tpl . $ | quote }} + http: + paths: + {{- include "loki.ingress.servicePaths" $ | indent 10}} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/loki-canary/_helpers.tpl b/charts/loki/templates/loki-canary/_helpers.tpl new file mode 100644 index 0000000..01e588c --- /dev/null +++ b/charts/loki/templates/loki-canary/_helpers.tpl @@ -0,0 +1,40 @@ +{{/* +canary fullname +*/}} +{{- define "loki-canary.fullname" -}} +{{ include "loki.name" . }}-canary +{{- end }} + +{{/* +canary common labels +*/}} +{{- define "loki-canary.labels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: canary +{{- end }} + +{{/* +canary selector labels +*/}} +{{- define "loki-canary.selectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: canary +{{- end }} + +{{/* +Docker image name for loki-canary +*/}} +{{- define "loki-canary.image" -}} +{{- $dict := dict "service" .Values.lokiCanary.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}} +{{- include "loki.baseImage" $dict -}} +{{- end -}} + +{{/* +canary priority class name +*/}} +{{- define "loki-canary.priorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.lokiCanary.priorityClassName .Values.read.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/loki-canary/daemonset.yaml b/charts/loki/templates/loki-canary/daemonset.yaml new file mode 100644 index 0000000..dc5c629 --- /dev/null +++ b/charts/loki/templates/loki-canary/daemonset.yaml @@ -0,0 +1,123 @@ +{{- with .Values.lokiCanary -}} +{{- if .enabled -}} +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "loki-canary.fullname" $ }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki-canary.labels" $ | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki-canary.selectorLabels" $ | nindent 6 }} + {{- with .updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki-canary.selectorLabels" $ | nindent 8 }} + {{- with .podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki-canary.fullname" $ }} + {{- with $.Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki-canary.priorityClassName" $ | nindent 6 }} + securityContext: + {{- toYaml $.Values.loki.podSecurityContext | nindent 8 }} + containers: + - name: loki-canary + image: {{ include "loki-canary.image" $ }} + imagePullPolicy: {{ $.Values.loki.image.pullPolicy }} + args: + - -addr={{- include "loki.host" $ }} + - -labelname={{ .labelname }} + - -labelvalue=$(POD_NAME) + {{- if $.Values.enterprise.enabled }} + - -user=$(USER) + - -tenant-id=$(USER) + - -pass=$(PASS) + {{- else if $.Values.loki.auth_enabled }} + - -user={{ $.Values.monitoring.selfMonitoring.tenant.name }} + - -tenant-id={{ $.Values.monitoring.selfMonitoring.tenant.name }} + - -pass={{ $.Values.monitoring.selfMonitoring.tenant.password }} + {{- end }} + {{- if .push }} + - -push=true + {{- end }} + {{- with .extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml $.Values.loki.containerSecurityContext | nindent 12 }} + volumeMounts: + {{- with $.Values.lokiCanary.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3500 + protocol: TCP + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + {{ if $.Values.enterprise.enabled }} + - name: USER + valueFrom: + secretKeyRef: + name: {{ include "enterprise-logs.selfMonitoringTenantSecret" $ }} + key: username + - name: PASS + valueFrom: + secretKeyRef: + name: {{ include "enterprise-logs.selfMonitoringTenantSecret" $ }} + key: password + {{- end -}} + {{- with .extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + readinessProbe: + httpGet: + path: /metrics + port: http-metrics + initialDelaySeconds: 15 + timeoutSeconds: 1 + {{- with .resources}} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + {{- with $.Values.lokiCanary.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/loki-canary/service.yaml b/charts/loki/templates/loki-canary/service.yaml new file mode 100644 index 0000000..38022a3 --- /dev/null +++ b/charts/loki/templates/loki-canary/service.yaml @@ -0,0 +1,34 @@ +{{- with .Values.lokiCanary -}} +{{- if .enabled -}} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki-canary.fullname" $ }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki-canary.labels" $ | nindent 4 }} + {{- with $.Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + annotations: + {{- with $.Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3500 + targetPort: http-metrics + protocol: TCP + selector: + {{- include "loki-canary.selectorLabels" $ | nindent 4 }} +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/loki-canary/serviceaccount.yaml b/charts/loki/templates/loki-canary/serviceaccount.yaml new file mode 100644 index 0000000..2c1f79a --- /dev/null +++ b/charts/loki/templates/loki-canary/serviceaccount.yaml @@ -0,0 +1,21 @@ +{{- with .Values.lokiCanary -}} +{{- if .enabled -}} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "loki-canary.fullname" $ }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki-canary.labels" $ | nindent 4 }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ $.Values.serviceAccount.automountServiceAccountToken }} +{{- with $.Values.serviceAccount.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/memcached/_memcached-statefulset.tpl b/charts/loki/templates/memcached/_memcached-statefulset.tpl new file mode 100644 index 0000000..cb798e5 --- /dev/null +++ b/charts/loki/templates/memcached/_memcached-statefulset.tpl @@ -0,0 +1,180 @@ +{{/* +memcached StatefulSet +Params: + ctx = . context + valuesSection = name of the section in values.yaml + component = name of the component +valuesSection and component are specified separately because helm prefers camelcase for naming convetion and k8s components are named with snake case. +*/}} +{{- define "loki.memcached.statefulSet" -}} +{{ with (index $.ctx.Values $.valuesSection) }} +{{- if .enabled -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.resourceName" (dict "ctx" $.ctx "component" $.component) }} + labels: + {{- include "loki.labels" $.ctx | nindent 4 }} + app.kubernetes.io/component: "memcached-{{ $.component }}" + name: "memcached-{{ $.component }}" + annotations: + {{- toYaml .annotations | nindent 4 }} + namespace: {{ $.ctx.Release.Namespace | quote }} +spec: + podManagementPolicy: {{ .podManagementPolicy }} + replicas: {{ .replicas }} + selector: + matchLabels: + {{- include "loki.selectorLabels" $.ctx | nindent 6 }} + app.kubernetes.io/component: "memcached-{{ $.component }}" + name: "memcached-{{ $.component }}" + updateStrategy: + {{- toYaml .statefulStrategy | nindent 4 }} + serviceName: {{ template "loki.fullname" $.ctx }}-{{ $.component }} + + template: + metadata: + labels: + {{- include "loki.selectorLabels" $.ctx | nindent 8 }} + app.kubernetes.io/component: "memcached-{{ $.component }}" + name: "memcached-{{ $.component }}" + {{- with $.ctx.Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{- with $.ctx.Values.global.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + + spec: + serviceAccountName: {{ template "loki.serviceAccountName" $.ctx }} + {{- if .priorityClassName }} + priorityClassName: {{ .priorityClassName }} + {{- end }} + securityContext: + {{- toYaml $.ctx.Values.memcached.podSecurityContext | nindent 8 }} + initContainers: + {{- toYaml .initContainers | nindent 8 }} + nodeSelector: + {{- toYaml .nodeSelector | nindent 8 }} + affinity: + {{- toYaml .affinity | nindent 8 }} + topologySpreadConstraints: + {{- toYaml .topologySpreadConstraints | nindent 8 }} + tolerations: + {{- toYaml .tolerations | nindent 8 }} + terminationGracePeriodSeconds: {{ .terminationGracePeriodSeconds }} + {{- with $.ctx.Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .extraVolumes }} + volumes: + {{- toYaml .extraVolumes | nindent 8 }} + {{- end }} + containers: + {{- if .extraContainers }} + {{ toYaml .extraContainers | nindent 8 }} + {{- end }} + - name: memcached + {{- with $.ctx.Values.memcached.image }} + image: {{ .repository }}:{{ .tag }} + imagePullPolicy: {{ .pullPolicy }} + {{- end }} + resources: + {{- if .resources }} + {{- toYaml .resources | nindent 12 }} + {{- else }} + {{- /* Calculate requested memory as round(allocatedMemory * 1.2). But with integer built-in operators. */}} + {{- $requestMemory := div (add (mul .allocatedMemory 12) 5) 10 }} + limits: + memory: {{ $requestMemory }}Mi + requests: + cpu: 500m + memory: {{ $requestMemory }}Mi + {{- end }} + ports: + - containerPort: {{ .port }} + name: client + {{- /* Calculate storage size as round(.persistence.storageSize * 0.9). But with integer built-in operators. */}} + {{- $persistenceSize := (div (mul (trimSuffix "Gi" .persistence.storageSize | trimSuffix "G") 9) 10 ) }} + args: + - -m {{ .allocatedMemory }} + - --extended=modern,track_sizes{{ if .persistence.enabled }},ext_path={{ .persistence.mountPath }}/file:{{ $persistenceSize }}G,ext_wbuf_size=16{{ end }}{{ with .extraExtendedOptions }},{{ . }}{{ end }} + - -I {{ .maxItemMemory }}m + - -c {{ .connectionLimit }} + - -v + - -u {{ .port }} + {{- range $key, $value := .extraArgs }} + - "-{{ $key }}{{ if $value }} {{ $value }}{{ end }}" + {{- end }} + env: + {{- with $.ctx.Values.global.extraEnv }} + {{ toYaml . | nindent 12 }} + {{- end }} + envFrom: + {{- with $.ctx.Values.global.extraEnvFrom }} + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml $.ctx.Values.memcached.containerSecurityContext | nindent 12 }} + {{- if or .persistence.enabled .extraVolumeMounts }} + volumeMounts: + {{- if .persistence.enabled }} + - name: data + mountPath: {{ .persistence.mountPath }} + {{- end }} + {{- if .extraVolumeMounts }} + {{- toYaml .extraVolumeMounts | nindent 12 }} + {{- end }} + {{- end }} + + {{- if $.ctx.Values.memcachedExporter.enabled }} + - name: exporter + {{- with $.ctx.Values.memcachedExporter.image }} + image: {{ .repository}}:{{ .tag }} + imagePullPolicy: {{ .pullPolicy }} + {{- end }} + ports: + - containerPort: 9150 + name: http-metrics + args: + - "--memcached.address=localhost:{{ .port }}" + - "--web.listen-address=0.0.0.0:9150" + {{- range $key, $value := $.ctx.Values.memcachedExporter.extraArgs }} + - "--{{ $key }}{{ if $value }}={{ $value }}{{ end }}" + {{- end }} + resources: + {{- toYaml $.ctx.Values.memcachedExporter.resources | nindent 12 }} + securityContext: + {{- toYaml $.ctx.Values.memcachedExporter.containerSecurityContext | nindent 12 }} + {{- if .extraVolumeMounts }} + volumeMounts: + {{- toYaml .extraVolumeMounts | nindent 12 }} + {{- end }} + {{- end }} + {{- if .persistence.enabled }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + spec: + accessModes: [ "ReadWriteOnce" ] + {{- with .persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .persistence.storageSize | quote }} + {{- end }} +{{- end -}} +{{- end -}} +{{- end -}} + diff --git a/charts/loki/templates/memcached/_memcached-svc.tpl b/charts/loki/templates/memcached/_memcached-svc.tpl new file mode 100644 index 0000000..8574151 --- /dev/null +++ b/charts/loki/templates/memcached/_memcached-svc.tpl @@ -0,0 +1,42 @@ +{{/* +memcached Service +Params: + ctx = . context + valuesSection = name of the section in values.yaml + component = name of the component +valuesSection and component are specified separately because helm prefers camelcase for naming convetion and k8s components are named with snake case. +*/}} +{{- define "loki.memcached.service" -}} +{{ with (index $.ctx.Values $.valuesSection) }} +{{- if .enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.resourceName" (dict "ctx" $.ctx "component" $.component) }} + labels: + {{- include "loki.labels" $.ctx | nindent 4 }} + app.kubernetes.io/component: "memcached-{{ $.component }}" + {{- with .service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- toYaml .service.annotations | nindent 4 }} + namespace: {{ $.ctx.Release.Namespace | quote }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: memcached-client + port: {{ .port }} + targetPort: {{ .port }} + {{ if $.ctx.Values.memcachedExporter.enabled -}} + - name: http-metrics + port: 9150 + targetPort: 9150 + {{ end }} + selector: + {{- include "loki.selectorLabels" $.ctx | nindent 4 }} + app.kubernetes.io/component: "memcached-{{ $.component }}" +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/monitoring/_helpers-monitoring.tpl b/charts/loki/templates/monitoring/_helpers-monitoring.tpl new file mode 100644 index 0000000..cb693e4 --- /dev/null +++ b/charts/loki/templates/monitoring/_helpers-monitoring.tpl @@ -0,0 +1,47 @@ +{{/* +Client definition for LogsInstance +*/}} +{{- define "loki.logsInstanceClient" -}} +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- $url := printf "http://%s.%s.svc.%s:%s/loki/api/v1/push" (include "loki.writeFullname" .) .Release.Namespace .Values.global.clusterDomain ( .Values.loki.server.http_listen_port | toString ) }} +{{- if $isSingleBinary }} + {{- $url = printf "http://%s.%s.svc.%s:%s/loki/api/v1/push" (include "loki.singleBinaryFullname" .) .Release.Namespace .Values.global.clusterDomain ( .Values.loki.server.http_listen_port | toString ) }} +{{- else if .Values.gateway.enabled -}} + {{- $url = printf "http://%s.%s.svc.%s/loki/api/v1/push" (include "loki.gatewayFullname" .) .Release.Namespace .Values.global.clusterDomain }} +{{- end -}} +- url: {{ $url }} + externalLabels: + cluster: {{ include "loki.clusterLabel" . }} + {{- if .Values.enterprise.enabled }} + basicAuth: + username: + name: {{ include "enterprise-logs.selfMonitoringTenantSecret" . }} + key: username + password: + name: {{ include "enterprise-logs.selfMonitoringTenantSecret" . }} + key: password + {{- else if .Values.loki.auth_enabled }} + tenantId: {{ .Values.monitoring.selfMonitoring.tenant.name | quote }} + {{- end }} +{{- end -}} + +{{/* +Convert a recording rule group to yaml +*/}} +{{- define "loki.ruleGroupToYaml" -}} +{{- range . }} +- name: {{ .name }} + rules: + {{- toYaml .rules | nindent 4 }} +{{- end }} +{{- end }} + +{{/* +GrafanaAgent priority class name +*/}} +{{- define "grafana-agent.priorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.monitoring.selfMonitoring.grafanaAgent.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/monitoring/dashboards/_helpers-dashboards.tpl b/charts/loki/templates/monitoring/dashboards/_helpers-dashboards.tpl new file mode 100644 index 0000000..00fd722 --- /dev/null +++ b/charts/loki/templates/monitoring/dashboards/_helpers-dashboards.tpl @@ -0,0 +1,6 @@ +{{/* +dashboards name +*/}} +{{- define "loki.dashboardsName" -}} +{{ include "loki.name" . }}-dashboards +{{- end }} diff --git a/charts/loki/templates/monitoring/dashboards/configmap-1.yaml b/charts/loki/templates/monitoring/dashboards/configmap-1.yaml new file mode 100644 index 0000000..6352f25 --- /dev/null +++ b/charts/loki/templates/monitoring/dashboards/configmap-1.yaml @@ -0,0 +1,30 @@ +{{- with .Values.monitoring.dashboards }} +{{- if .enabled }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "loki.dashboardsName" $ }}-1 + namespace: {{ .namespace | default $.Release.Namespace }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + "loki-chunks.json": | + {{ $.Files.Get "src/dashboards/loki-chunks.json" | fromJson | toJson }} + "loki-deletion.json": | + {{ $.Files.Get "src/dashboards/loki-deletion.json" | fromJson | toJson }} + "loki-logs.json": | + {{ $.Files.Get "src/dashboards/loki-logs.json" | fromJson | toJson }} + "loki-mixin-recording-rules.json": | + {{ $.Files.Get "src/dashboards/loki-mixin-recording-rules.json" | fromJson | toJson }} + "loki-operational.json": | + {{ $.Files.Get "src/dashboards/loki-operational.json" | fromJson | toJson }} +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/monitoring/dashboards/configmap-2.yaml b/charts/loki/templates/monitoring/dashboards/configmap-2.yaml new file mode 100644 index 0000000..67d3cf4 --- /dev/null +++ b/charts/loki/templates/monitoring/dashboards/configmap-2.yaml @@ -0,0 +1,30 @@ +{{- with .Values.monitoring.dashboards }} +{{- if .enabled }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "loki.dashboardsName" $ }}-2 + namespace: {{ .namespace | default $.Release.Namespace }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + "loki-reads-resources.json": | + {{ $.Files.Get "src/dashboards/loki-reads-resources.json" | fromJson | toJson }} + "loki-reads.json": | + {{ $.Files.Get "src/dashboards/loki-reads.json" | fromJson | toJson }} + "loki-retention.json": | + {{ $.Files.Get "src/dashboards/loki-retention.json" | fromJson | toJson }} + "loki-writes-resources.json": | + {{ $.Files.Get "src/dashboards/loki-writes-resources.json" | fromJson | toJson }} + "loki-writes.json": | + {{ $.Files.Get "src/dashboards/loki-writes.json" | fromJson | toJson }} +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/monitoring/grafana-agent.yaml b/charts/loki/templates/monitoring/grafana-agent.yaml new file mode 100644 index 0000000..a047e5f --- /dev/null +++ b/charts/loki/templates/monitoring/grafana-agent.yaml @@ -0,0 +1,100 @@ +{{- if .Values.monitoring.selfMonitoring.enabled }} +{{- with .Values.monitoring.selfMonitoring.grafanaAgent }} +apiVersion: monitoring.grafana.com/v1alpha1 +kind: GrafanaAgent +metadata: + name: {{ include "loki.fullname" $ }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + serviceAccountName: {{ include "loki.fullname" $ }}-grafana-agent + enableConfigReadAPI: {{ .enableConfigReadAPI }} + {{- include "grafana-agent.priorityClassName" $ | nindent 2 }} + logs: + instanceSelector: + matchLabels: + {{- include "loki.selectorLabels" $ | nindent 8 }} + {{- with $.Values.monitoring.serviceMonitor}} + {{- if .metricsInstance.remoteWrite}} + metrics: + instanceSelector: + matchLabels: + {{- include "loki.selectorLabels" $ | nindent 8 }} + {{- end }} + {{- end }} + {{- with .resources }} + resources: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .tolerations }} + tolerations: + {{- toYaml . | nindent 4 }} + {{- end }} + +--- + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "loki.fullname" $ }}-grafana-agent + namespace: {{ .namespace | default $.Release.Namespace }} + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "loki.fullname" $ }}-grafana-agent +rules: +- apiGroups: + - "" + resources: + - nodes + - nodes/proxy + - nodes/metrics + - services + - endpoints + - pods + - events + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- nonResourceURLs: + - /metrics + - /metrics/cadvisor + verbs: + - get + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "loki.fullname" $ }}-grafana-agent +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "loki.fullname" $ }}-grafana-agent +subjects: +- kind: ServiceAccount + name: {{ include "loki.fullname" $ }}-grafana-agent + namespace: {{ .namespace | default $.Release.Namespace }} +{{- end}} +{{- end}} diff --git a/charts/loki/templates/monitoring/logs-instance.yaml b/charts/loki/templates/monitoring/logs-instance.yaml new file mode 100644 index 0000000..5ae1917 --- /dev/null +++ b/charts/loki/templates/monitoring/logs-instance.yaml @@ -0,0 +1,30 @@ +{{- if .Values.monitoring.selfMonitoring.enabled }} +{{- with .Values.monitoring.selfMonitoring.logsInstance }} +apiVersion: monitoring.grafana.com/v1alpha1 +kind: LogsInstance +metadata: + name: {{ include "loki.fullname" $ }} + namespace: {{ $.Release.Namespace }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + clients: + {{- include "loki.logsInstanceClient" $ | nindent 4}} + {{- with .clients}} + {{- toYaml . | nindent 4 }} + {{- end }} + + podLogsNamespaceSelector: {} + + podLogsSelector: + matchLabels: + {{- include "loki.selectorLabels" $ | nindent 6 }} +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/charts/loki/templates/monitoring/loki-alerts.yaml b/charts/loki/templates/monitoring/loki-alerts.yaml new file mode 100644 index 0000000..f3333df --- /dev/null +++ b/charts/loki/templates/monitoring/loki-alerts.yaml @@ -0,0 +1,22 @@ +{{- with .Values.monitoring.rules }} +{{- if and ($.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/PrometheusRule") .enabled .alerting }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "loki.fullname" $ }}-loki-alerts + namespace: {{ .namespace | default $.Release.Namespace }} +spec: + groups: + {{- include "loki.ruleGroupToYaml" (tpl ($.Files.Get "src/alerts.yaml.tpl") $ | fromYaml).groups | indent 4 }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/monitoring/loki-rules.yaml b/charts/loki/templates/monitoring/loki-rules.yaml new file mode 100644 index 0000000..f9eb392 --- /dev/null +++ b/charts/loki/templates/monitoring/loki-rules.yaml @@ -0,0 +1,23 @@ +{{- with .Values.monitoring.rules }} +{{- if and ($.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/PrometheusRule") .enabled }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "loki.fullname" $ }}-loki-rules + namespace: {{ .namespace | default $.Release.Namespace }} +spec: + groups: + {{- include "loki.ruleGroupToYaml" (tpl ($.Files.Get "src/rules.yaml.tpl") $ | fromYaml).groups | indent 4 }} + {{- include "loki.ruleGroupToYaml" .additionalGroups | indent 4 }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/monitoring/metrics-instance.yaml b/charts/loki/templates/monitoring/metrics-instance.yaml new file mode 100644 index 0000000..82102c0 --- /dev/null +++ b/charts/loki/templates/monitoring/metrics-instance.yaml @@ -0,0 +1,30 @@ +{{- if .Values.monitoring.serviceMonitor.enabled }} +{{- with .Values.monitoring.serviceMonitor.metricsInstance }} +{{- if and ($.Capabilities.APIVersions.Has "monitoring.grafana.com/v1alpha1/MetricsInstance") .enabled }} +apiVersion: monitoring.grafana.com/v1alpha1 +kind: MetricsInstance +metadata: + name: {{ include "loki.fullname" $ }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .remoteWrite}} + remoteWrite: + {{- toYaml . | nindent 4 }} + {{- end }} + + serviceMonitorNamespaceSelector: {} + + serviceMonitorSelector: + matchLabels: + {{- include "loki.selectorLabels" $ | nindent 6 }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/monitoring/pod-logs.yaml b/charts/loki/templates/monitoring/pod-logs.yaml new file mode 100644 index 0000000..317339d --- /dev/null +++ b/charts/loki/templates/monitoring/pod-logs.yaml @@ -0,0 +1,62 @@ +--- +{{- if .Values.monitoring.selfMonitoring.enabled }} +{{- with .Values.monitoring.selfMonitoring.podLogs }} +apiVersion: {{ .apiVersion }} +kind: PodLogs +metadata: + name: {{ include "loki.fullname" $ }} + namespace: {{ $.Release.Namespace }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + pipelineStages: + - cri: { } + {{- with .additionalPipelineStages }} + {{- toYaml . | nindent 4 }} + {{- end }} + relabelings: + - action: replace + sourceLabels: + - __meta_kubernetes_pod_node_name + targetLabel: __host__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + replacement: "$1" + separator: "-" + sourceLabels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + targetLabel: __service__ + - action: replace + replacement: "$1" + separator: "/" + sourceLabels: + - __meta_kubernetes_namespace + - __service__ + targetLabel: job + - action: replace + sourceLabels: + - __meta_kubernetes_pod_container_name + targetLabel: container + - action: replace + replacement: "{{ include "loki.clusterLabel" $ }}" + targetLabel: cluster + {{- with .relabelings }} + {{- toYaml . | nindent 4 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ $.Release.Namespace }} + selector: + matchLabels: + {{- include "loki.selectorLabels" $ | nindent 6 }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/monitoring/servicemonitor.yaml b/charts/loki/templates/monitoring/servicemonitor.yaml new file mode 100644 index 0000000..856cee8 --- /dev/null +++ b/charts/loki/templates/monitoring/servicemonitor.yaml @@ -0,0 +1,63 @@ +{{- with .Values.monitoring.serviceMonitor }} +{{- if and ($.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor") .enabled }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "loki.fullname" $ }} + namespace: {{ $.Release.Namespace }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- include "loki.selectorLabels" $ | nindent 6 }} + matchExpressions: + - key: prometheus.io/service-monitor + operator: NotIn + values: + - "false" + endpoints: + - port: http-metrics + path: /metrics + {{- with .interval }} + interval: {{ . }} + {{- end }} + {{- with .scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + relabelings: + - sourceLabels: [job] + action: replace + replacement: "{{ $.Release.Namespace }}/$1" + targetLabel: job + - action: replace + replacement: "{{ include "loki.clusterLabel" $ }}" + targetLabel: cluster + {{- with .relabelings }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .scheme }} + scheme: {{ . }} + {{- end }} + {{- with .tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/networkpolicy.yaml b/charts/loki/templates/networkpolicy.yaml new file mode 100644 index 0000000..9286edb --- /dev/null +++ b/charts/loki/templates/networkpolicy.yaml @@ -0,0 +1,203 @@ +{{- if and (.Values.networkPolicy.enabled) (eq .Values.networkPolicy.flavor "kubernetes") }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-namespace-only + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Ingress + - Egress + podSelector: {} + egress: + - to: + - podSelector: {} + ingress: + - from: + - podSelector: {} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-dns + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Egress + podSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + egress: + - ports: + - port: dns + protocol: UDP + to: + - namespaceSelector: {} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-ingress + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Ingress + podSelector: + matchExpressions: + - key: app.kubernetes.io/component + operator: In + values: + {{- if .Values.gateway.enabled }} + - gateway + {{- else }} + - read + - write + {{- end }} + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + ingress: + - ports: + - port: http-metrics + protocol: TCP + {{- if .Values.networkPolicy.ingress.namespaceSelector }} + from: + - namespaceSelector: + {{- toYaml .Values.networkPolicy.ingress.namespaceSelector | nindent 12 }} + {{- if .Values.networkPolicy.ingress.podSelector }} + podSelector: + {{- toYaml .Values.networkPolicy.ingress.podSelector | nindent 12 }} + {{- end }} + {{- end }} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-ingress-metrics + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Ingress + podSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + ingress: + - ports: + - port: http-metrics + protocol: TCP + {{- if .Values.networkPolicy.metrics.cidrs }} + from: + {{- range $cidr := .Values.networkPolicy.metrics.cidrs }} + - ipBlock: + cidr: {{ $cidr }} + {{- end }} + {{- if .Values.networkPolicy.metrics.namespaceSelector }} + - namespaceSelector: + {{- toYaml .Values.networkPolicy.metrics.namespaceSelector | nindent 12 }} + {{- if .Values.networkPolicy.metrics.podSelector }} + podSelector: + {{- toYaml .Values.networkPolicy.metrics.podSelector | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-alertmanager + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Egress + podSelector: + matchLabels: + {{- include "loki.backendSelectorLabels" . | nindent 6 }} + egress: + - ports: + - port: {{ .Values.networkPolicy.alertmanager.port }} + protocol: TCP + {{- if .Values.networkPolicy.alertmanager.namespaceSelector }} + to: + - namespaceSelector: + {{- toYaml .Values.networkPolicy.alertmanager.namespaceSelector | nindent 12 }} + {{- if .Values.networkPolicy.alertmanager.podSelector }} + podSelector: + {{- toYaml .Values.networkPolicy.alertmanager.podSelector | nindent 12 }} + {{- end }} + {{- end }} + +{{- if .Values.networkPolicy.externalStorage.ports }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-external-storage + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Egress + podSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + egress: + - ports: + {{- range $port := .Values.networkPolicy.externalStorage.ports }} + - port: {{ $port }} + protocol: TCP + {{- end }} + {{- if .Values.networkPolicy.externalStorage.cidrs }} + to: + {{- range $cidr := .Values.networkPolicy.externalStorage.cidrs }} + - ipBlock: + cidr: {{ $cidr }} + {{- end }} + {{- end }} +{{- end }} + +{{- end }} + +{{- if and .Values.networkPolicy.discovery.port (eq .Values.networkPolicy.flavor "kubernetes") }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-discovery + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Egress + podSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + egress: + - ports: + - port: {{ .Values.networkPolicy.discovery.port }} + protocol: TCP + {{- if .Values.networkPolicy.discovery.namespaceSelector }} + to: + - namespaceSelector: + {{- toYaml .Values.networkPolicy.discovery.namespaceSelector | nindent 12 }} + {{- if .Values.networkPolicy.discovery.podSelector }} + podSelector: + {{- toYaml .Values.networkPolicy.discovery.podSelector | nindent 12 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/overrides-exporter/_helpers-overrides-exporter.tpl b/charts/loki/templates/overrides-exporter/_helpers-overrides-exporter.tpl new file mode 100644 index 0000000..1baa60e --- /dev/null +++ b/charts/loki/templates/overrides-exporter/_helpers-overrides-exporter.tpl @@ -0,0 +1,32 @@ +{{/* +overrides-exporter fullname +*/}} +{{- define "loki.overridesExporterFullname" -}} +{{ include "loki.fullname" . }}-overrides-exporter +{{- end }} + +{{/* +overrides-exporter common labels +*/}} +{{- define "loki.overridesExporterLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: overrides-exporter +{{- end }} + +{{/* +overrides-exporter selector labels +*/}} +{{- define "loki.overridesExporterSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: overrides-exporter +{{- end }} + +{{/* +overrides-exporter priority class name +*/}} +{{- define "loki.overridesExporterPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.overridesExporter.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/overrides-exporter/deployment-overrides-exporter.yaml b/charts/loki/templates/overrides-exporter/deployment-overrides-exporter.yaml new file mode 100644 index 0000000..f214ce5 --- /dev/null +++ b/charts/loki/templates/overrides-exporter/deployment-overrides-exporter.yaml @@ -0,0 +1,143 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.overridesExporter.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.overridesExporterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.overridesExporterLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.overridesExporter.replicas }} + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.overridesExporterSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.overridesExporter.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.overridesExporterLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.overridesExporter.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.overridesExporter.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.overridesExporter.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.overridesExporterPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.overridesExporter.terminationGracePeriodSeconds }} + containers: + - name: overrides-exporter + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.overridesExporter.command }} + command: + - {{ coalesce .Values.overridesExporter.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=overrides-exporter + {{- with (concat .Values.global.extraArgs .Values.overridesExporter.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.overridesExporter.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.overridesExporter.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.overridesExporter.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.overridesExporter.resources | nindent 12 }} + {{- if .Values.overridesExporter.extraContainers }} + {{- toYaml .Values.overridesExporter.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.overridesExporter.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.overridesExporter.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.overridesExporter.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.overridesExporter.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end -}} diff --git a/charts/loki/templates/overrides-exporter/poddisruptionbudget-overrides-exporter.yaml b/charts/loki/templates/overrides-exporter/poddisruptionbudget-overrides-exporter.yaml new file mode 100644 index 0000000..d8be6f4 --- /dev/null +++ b/charts/loki/templates/overrides-exporter/poddisruptionbudget-overrides-exporter.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.overridesExporter.enabled (gt (int .Values.overridesExporter.replicas) 1) }} +{{- if kindIs "invalid" .Values.overridesExporter.maxUnavailable }} +{{- fail "`.Values.overridesExporter.maxUnavailable` must be set when `.Values.overridesExporter.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.overridesExporterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.overridesExporterLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.overridesExporterSelectorLabels" . | nindent 6 }} + {{- with .Values.overridesExporter.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/overrides-exporter/service-overrides-exporter-headless.yaml b/charts/loki/templates/overrides-exporter/service-overrides-exporter-headless.yaml new file mode 100644 index 0000000..a645a8e --- /dev/null +++ b/charts/loki/templates/overrides-exporter/service-overrides-exporter-headless.yaml @@ -0,0 +1,39 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.overridesExporter.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.overridesExporterFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.overridesExporterLabels" . | nindent 4 }} + {{- with .Values.overridesExporter.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.overridesExporter.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + type: ClusterIP + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.overridesExporter.appProtocol.grpc }} + appProtocol: {{ .Values.overridesExporter.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.overridesExporterSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/templates/overrides-exporter/service-overrides-exporter.yaml b/charts/loki/templates/overrides-exporter/service-overrides-exporter.yaml new file mode 100644 index 0000000..847aa2f --- /dev/null +++ b/charts/loki/templates/overrides-exporter/service-overrides-exporter.yaml @@ -0,0 +1,37 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.overridesExporter.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.overridesExporterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.overridesExporterLabels" . | nindent 4 }} + {{- with .Values.overridesExporter.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.overridesExporter.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.overridesExporter.appProtocol.grpc }} + appProtocol: {{ .Values.overridesExporter.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.overridesExporterSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/templates/pattern-ingester/_helpers-pattern-ingester.tpl b/charts/loki/templates/pattern-ingester/_helpers-pattern-ingester.tpl new file mode 100644 index 0000000..5477214 --- /dev/null +++ b/charts/loki/templates/pattern-ingester/_helpers-pattern-ingester.tpl @@ -0,0 +1,58 @@ +{{/* +pattern ingester fullname +*/}} +{{- define "loki.patternIngesterFullname" -}} +{{ include "loki.fullname" . }}-pattern-ingester +{{- end }} + +{{/* +pattern ingester common labels +*/}} +{{- define "loki.patternIngesterLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: pattern-ingester +{{- end }} + +{{/* +pattern ingester selector labels +*/}} +{{- define "loki.patternIngesterSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: pattern-ingester +{{- end }} + +{{/* +pattern ingester readinessProbe +*/}} +{{- define "loki.patternIngester.readinessProbe" -}} +{{- with .Values.patternIngester.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +pattern ingester priority class name +*/}} +{{- define "loki.patternIngesterPriorityClassName" }} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.patternIngester.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} + +{{/* +Create the name of the pattern ingester service account +*/}} +{{- define "loki.patternIngesterServiceAccountName" -}} +{{- if .Values.patternIngester.serviceAccount.create -}} + {{ default (print (include "loki.serviceAccountName" .) "-pattern-ingester") .Values.patternIngester.serviceAccount.name }} +{{- else -}} + {{ default (include "loki.serviceAccountName" .) .Values.patternIngester.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/pattern-ingester/statefulset-pattern-ingester.yaml b/charts/loki/templates/pattern-ingester/statefulset-pattern-ingester.yaml new file mode 100644 index 0000000..7756b40 --- /dev/null +++ b/charts/loki/templates/pattern-ingester/statefulset-pattern-ingester.yaml @@ -0,0 +1,186 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +{{- if (gt (int .Values.patternIngester.replicas) 0) -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.patternIngesterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.patternIngesterLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.patternIngester.replicas }} + podManagementPolicy: Parallel + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.patternIngesterFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.patternIngester.persistence.enableStatefulSetAutoDeletePVC) }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.patternIngester.persistence.whenDeleted }} + whenScaled: {{ .Values.patternIngester.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.patternIngesterSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.patternIngester.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.patternIngesterLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.patternIngester.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.patternIngester.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.patternIngesterPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.patternIngester.terminationGracePeriodSeconds }} + {{- with .Values.patternIngester.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: pattern-ingester + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.patternIngester.command }} + command: + - {{ coalesce .Values.patternIngester.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=pattern-ingester + {{- with (concat .Values.global.extraArgs .Values.patternIngester.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.patternIngester.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.patternIngester.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.patternIngester.readinessProbe" . | nindent 10 }} + volumeMounts: + - name: temp + mountPath: /tmp + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.patternIngester.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.patternIngester.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.patternIngester.extraContainers }} + {{- toYaml .Values.patternIngester.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.patternIngester.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.patternIngester.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.patternIngester.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.patternIngester.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: temp + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- if not .Values.patternIngester.persistence.enabled }} + - name: data + emptyDir: {} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.patternIngester.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.patternIngester.persistence.enabled }} + volumeClaimTemplates: + {{- range .Values.patternIngester.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end -}} +{{- end -}} diff --git a/charts/loki/templates/podsecuritypolicy.yaml b/charts/loki/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000..05470d9 --- /dev/null +++ b/charts/loki/templates/podsecuritypolicy.yaml @@ -0,0 +1,41 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "loki.name" . }} + labels: + {{- include "loki.labels" . | nindent 4 }} +{{- if .Values.rbac.pspAnnotations }} + annotations: +{{ toYaml .Values.rbac.pspAnnotations | indent 4 }} +{{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + volumes: + - 'configMap' + - 'emptyDir' + - 'persistentVolumeClaim' + - 'secret' + - 'projected' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAsNonRoot' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + readOnlyRootFilesystem: true + requiredDropCapabilities: + - ALL +{{- end }} diff --git a/charts/loki/templates/provisioner/_helpers.yaml b/charts/loki/templates/provisioner/_helpers.yaml new file mode 100644 index 0000000..8b04b07 --- /dev/null +++ b/charts/loki/templates/provisioner/_helpers.yaml @@ -0,0 +1,32 @@ +{{/* +provisioner fullname +*/}} +{{- define "enterprise-logs.provisionerFullname" -}} +{{ include "loki.name" . }}-provisioner +{{- end }} + +{{/* +provisioner common labels +*/}} +{{- define "enterprise-logs.provisionerLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: provisioner +{{- end }} + +{{/* +provisioner selector labels +*/}} +{{- define "enterprise-logs.provisionerSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: provisioner +{{- end }} + +{{/* +provisioner image name +*/}} +{{- define "enterprise-logs.provisionerImage" -}} +{{- $dict := dict "service" .Values.enterprise.provisioner.image "global" .Values.global.image "defaultVersion" "latest" -}} +{{- include "loki.baseImage" $dict -}} +{{- end -}} + + diff --git a/charts/loki/templates/provisioner/job-provisioner.yaml b/charts/loki/templates/provisioner/job-provisioner.yaml new file mode 100644 index 0000000..2609f21 --- /dev/null +++ b/charts/loki/templates/provisioner/job-provisioner.yaml @@ -0,0 +1,147 @@ +{{ if and .Values.enterprise.provisioner.enabled .Values.enterprise.enabled }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "enterprise-logs.provisionerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "enterprise-logs.provisionerLabels" . | nindent 4 }} + {{- with .Values.enterprise.provisioner.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.provisioner.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": {{ .Values.enterprise.provisioner.hookType | default "post-install" | quote }} + "helm.sh/hook-weight": "15" +spec: + backoffLimit: 6 + completions: 1 + parallelism: 1 + template: + metadata: + labels: + {{- include "enterprise-logs.provisionerSelectorLabels" . | nindent 8 }} + {{- with .Values.enterprise.provisioner.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.enterprise.provisioner.annotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.enterprise.provisioner.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + securityContext: + {{- toYaml .Values.enterprise.provisioner.securityContext | nindent 8 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + initContainers: + - name: provisioner + image: {{ template "enterprise-logs.provisionerImage" . }} + imagePullPolicy: {{ .Values.enterprise.provisioner.image.pullPolicy }} + command: + - /bin/sh + - -exuc + - | + {{- range .Values.enterprise.provisioner.additionalTenants }} + /usr/bin/enterprise-logs-provisioner \ + -bootstrap-path=/bootstrap \ + -cluster-name={{ include "loki.clusterName" $ }} \ + -gel-url={{ include "loki.address" $ }} \ + -instance={{ .name }} \ + -access-policy=write-{{ .name }}:{{ .name }}:logs:write \ + -access-policy=read-{{ .name }}:{{ .name }}:logs:read \ + -token=write-{{ .name }} \ + -token=read-{{ .name }} + {{- end -}} + + {{- with .Values.monitoring.selfMonitoring.tenant }} + /usr/bin/enterprise-logs-provisioner \ + -bootstrap-path=/bootstrap \ + -cluster-name={{ include "loki.clusterName" $ }} \ + -gel-url={{ include "loki.address" $ }} \ + -instance={{ .name }} \ + -access-policy=self-monitoring:{{ .name }}:logs:write,logs:read \ + -token=self-monitoring + {{- end }} + volumeMounts: + {{- with .Values.enterprise.provisioner.extraVolumeMounts }} + {{ toYaml . | nindent 12 }} + {{- end }} + - name: bootstrap + mountPath: /bootstrap + - name: admin-token + mountPath: /bootstrap/token + subPath: token + {{- with .Values.enterprise.provisioner.env }} + env: + {{ toYaml . | nindent 12 }} + {{- end }} + containers: + - name: create-secret + image: {{ include "loki.kubectlImage" . }} + imagePullPolicy: {{ .Values.kubectlImage.pullPolicy }} + command: + - /bin/bash + - -exuc + - | + # In case, the admin resources have already been created, the provisioner job + # does not write the token files to the bootstrap mount. + # Therefore, secrets are only created if the respective token files exist. + # Note: the following bash commands should always return a success status code. + # Therefore, in case the token file does not exist, the first clause of the + # or-operation is successful. + {{- range .Values.enterprise.provisioner.additionalTenants }} + ! test -s /bootstrap/token-write-{{ .name }} || \ + kubectl --namespace "{{ .secretNamespace }}" create secret generic "{{ include "enterprise-logs.provisionedSecretPrefix" $ }}-{{ .name }}" \ + --from-literal=token-write="$(cat /bootstrap/token-write-{{ .name }})" \ + --from-literal=token-read="$(cat /bootstrap/token-read-{{ .name }})" + {{- end }} + {{- $namespace := $.Release.Namespace }} + {{- with .Values.monitoring.selfMonitoring.tenant }} + {{- $secretNamespace := tpl .secretNamespace $ }} + ! test -s /bootstrap/token-self-monitoring || \ + kubectl --namespace "{{ $namespace }}" create secret generic "{{ include "enterprise-logs.selfMonitoringTenantSecret" $ }}" \ + --from-literal=username="{{ .name }}" \ + --from-literal=password="$(cat /bootstrap/token-self-monitoring)" + {{- if not (eq $secretNamespace $namespace) }} + ! test -s /bootstrap/token-self-monitoring || \ + kubectl --namespace "{{ $secretNamespace }}" create secret generic "{{ include "enterprise-logs.selfMonitoringTenantSecret" $ }}" \ + --from-literal=username="{{ .name }}" \ + --from-literal=password="$(cat /bootstrap/token-self-monitoring)" + {{- end }} + {{- end }} + volumeMounts: + {{- with .Values.enterprise.provisioner.extraVolumeMounts }} + {{ toYaml . | nindent 12 }} + {{- end }} + - name: bootstrap + mountPath: /bootstrap + {{- with .Values.enterprise.provisioner.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.enterprise.provisioner.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.enterprise.provisioner.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + restartPolicy: OnFailure + serviceAccount: {{ include "enterprise-logs.provisionerFullname" . }} + serviceAccountName: {{ include "enterprise-logs.provisionerFullname" . }} + volumes: + - name: admin-token + secret: + secretName: "{{ include "enterprise-logs.adminTokenSecret" . }}" + - name: bootstrap + emptyDir: {} +{{- end }} diff --git a/charts/loki/templates/provisioner/role-provisioner.yaml b/charts/loki/templates/provisioner/role-provisioner.yaml new file mode 100644 index 0000000..4c8121f --- /dev/null +++ b/charts/loki/templates/provisioner/role-provisioner.yaml @@ -0,0 +1,21 @@ +{{ if and .Values.enterprise.provisioner.enabled .Values.enterprise.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ if not .Values.rbac.namespaced }}Cluster{{ end }}Role +metadata: + name: {{ template "enterprise-logs.provisionerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "enterprise-logs.provisionerLabels" . | nindent 4 }} + {{- with .Values.enterprise.provisioner.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.provisioner.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["create"] +{{- end }} diff --git a/charts/loki/templates/provisioner/rolebinding-provisioner.yaml b/charts/loki/templates/provisioner/rolebinding-provisioner.yaml new file mode 100644 index 0000000..5cd4560 --- /dev/null +++ b/charts/loki/templates/provisioner/rolebinding-provisioner.yaml @@ -0,0 +1,26 @@ +{{ if and .Values.enterprise.provisioner.enabled .Values.enterprise.enabled}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ if not .Values.rbac.namespaced }}Cluster{{ else }}Role{{ end }}Binding +metadata: + name: {{ template "enterprise-logs.provisionerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "enterprise-logs.provisionerLabels" . | nindent 4 }} + {{- with .Values.enterprise.provisioner.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.provisioner.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: {{ if not .Values.rbac.namespaced }}Cluster{{ end }}Role + name: {{ template "enterprise-logs.provisionerFullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "enterprise-logs.provisionerFullname" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} diff --git a/charts/loki/templates/provisioner/serviceaccount-provisioner.yaml b/charts/loki/templates/provisioner/serviceaccount-provisioner.yaml new file mode 100644 index 0000000..81e92e9 --- /dev/null +++ b/charts/loki/templates/provisioner/serviceaccount-provisioner.yaml @@ -0,0 +1,18 @@ +{{ if and .Values.enterprise.provisioner.enabled .Values.enterprise.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "enterprise-logs.provisionerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "enterprise-logs.provisionerLabels" . | nindent 4 }} + {{- with .Values.enterprise.provisioner.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.provisioner.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install +{{- end }} diff --git a/charts/loki/templates/querier/_helpers-querier.tpl b/charts/loki/templates/querier/_helpers-querier.tpl new file mode 100644 index 0000000..aa557c5 --- /dev/null +++ b/charts/loki/templates/querier/_helpers-querier.tpl @@ -0,0 +1,32 @@ +{{/* +querier fullname +*/}} +{{- define "loki.querierFullname" -}} +{{ include "loki.fullname" . }}-querier +{{- end }} + +{{/* +querier common labels +*/}} +{{- define "loki.querierLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: querier +{{- end }} + +{{/* +querier selector labels +*/}} +{{- define "loki.querierSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: querier +{{- end }} + +{{/* +querier priority class name +*/}} +{{- define "loki.querierPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.querier.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/querier/deployment-querier.yaml b/charts/loki/templates/querier/deployment-querier.yaml new file mode 100644 index 0000000..ffebc85 --- /dev/null +++ b/charts/loki/templates/querier/deployment-querier.yaml @@ -0,0 +1,163 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.querierFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querierLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.querier.autoscaling.enabled }} + replicas: {{ .Values.querier.replicas }} +{{- end }} + strategy: + rollingUpdate: + maxSurge: {{ .Values.querier.maxSurge }} + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.querierSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.querier.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.querierLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.querier.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.querier.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.querier.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.querierPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.querier.terminationGracePeriodSeconds }} + {{- with .Values.querier.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: querier + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=querier + {{- if .Values.ingester.zoneAwareReplication.enabled }} + {{- if and (.Values.ingester.zoneAwareReplication.migration.enabled) (not .Values.ingester.zoneAwareReplication.migration.readPath) }} + - -distributor.zone-awareness-enabled=false + {{- else }} + - -distributor.zone-awareness-enabled=true + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraArgs .Values.querier.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.querier.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.querier.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + livenessProbe: + {{- toYaml .Values.loki.livenessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.querier.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.querier.resources | nindent 12 }} + {{- if .Values.querier.extraContainers }} + {{- toYaml .Values.querier.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.querier.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.querier.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.querier.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.querier.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + - name: data + emptyDir: {} + {{- with (concat .Values.global.extraVolumes .Values.querier.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/querier/hpa.yaml b/charts/loki/templates/querier/hpa.yaml new file mode 100644 index 0000000..08d81cb --- /dev/null +++ b/charts/loki/templates/querier/hpa.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.querier.autoscaling.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.querierFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querierLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "loki.querierFullname" . }} + minReplicas: {{ .Values.querier.autoscaling.minReplicas }} + maxReplicas: {{ .Values.querier.autoscaling.maxReplicas }} + metrics: + {{- with .Values.querier.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.querier.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.querier.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.querier.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.querier.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.querier.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/querier/poddisruptionbudget-querier.yaml b/charts/loki/templates/querier/poddisruptionbudget-querier.yaml new file mode 100644 index 0000000..9dff3cd --- /dev/null +++ b/charts/loki/templates/querier/poddisruptionbudget-querier.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.querier.replicas) 1) }} +{{- if kindIs "invalid" .Values.querier.maxUnavailable }} +{{- fail "`.Values.querier.maxUnavailable` must be set when `.Values.querier.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.querierFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querierLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.querierSelectorLabels" . | nindent 6 }} + {{- with .Values.querier.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/querier/service-querier.yaml b/charts/loki/templates/querier/service-querier.yaml new file mode 100644 index 0000000..15c9c6a --- /dev/null +++ b/charts/loki/templates/querier/service-querier.yaml @@ -0,0 +1,36 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.querierFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querierLabels" . | nindent 4 }} + {{- with .Values.querier.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.querier.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.querier.appProtocol.grpc }} + appProtocol: {{ .Values.querier.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.querierSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/templates/query-frontend/_helpers-query-frontend.tpl b/charts/loki/templates/query-frontend/_helpers-query-frontend.tpl new file mode 100644 index 0000000..5aebde7 --- /dev/null +++ b/charts/loki/templates/query-frontend/_helpers-query-frontend.tpl @@ -0,0 +1,32 @@ +{{/* +query-frontend fullname +*/}} +{{- define "loki.queryFrontendFullname" -}} +{{ include "loki.fullname" . }}-query-frontend +{{- end }} + +{{/* +query-frontend common labels +*/}} +{{- define "loki.queryFrontendLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: query-frontend +{{- end }} + +{{/* +query-frontend selector labels +*/}} +{{- define "loki.queryFrontendSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: query-frontend +{{- end }} + +{{/* +query-frontend priority class name +*/}} +{{- define "loki.queryFrontendPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.queryFrontend.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/query-frontend/deployment-query-frontend.yaml b/charts/loki/templates/query-frontend/deployment-query-frontend.yaml new file mode 100644 index 0000000..1476d67 --- /dev/null +++ b/charts/loki/templates/query-frontend/deployment-query-frontend.yaml @@ -0,0 +1,145 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.queryFrontendFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.queryFrontendLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.queryFrontend.autoscaling.enabled }} + replicas: {{ .Values.queryFrontend.replicas }} +{{- end }} + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.queryFrontendSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryFrontend.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.queryFrontendLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.queryFrontend.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.queryFrontend.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryFrontend.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.queryFrontendPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.queryFrontend.terminationGracePeriodSeconds }} + containers: + - name: query-frontend + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.queryFrontend.command }} + command: + - {{ coalesce .Values.queryFrontend.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=query-frontend + {{- with (concat .Values.global.extraArgs .Values.queryFrontend.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.queryFrontend.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.queryFrontend.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.queryFrontend.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.queryFrontend.resources | nindent 12 }} + {{- if .Values.queryFrontend.extraContainers }} + {{- toYaml .Values.queryFrontend.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.queryFrontend.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryFrontend.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryFrontend.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.queryFrontend.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end -}} diff --git a/charts/loki/templates/query-frontend/hpa.yaml b/charts/loki/templates/query-frontend/hpa.yaml new file mode 100644 index 0000000..c326287 --- /dev/null +++ b/charts/loki/templates/query-frontend/hpa.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.queryFrontend.autoscaling.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.queryFrontendFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.queryFrontendLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "loki.queryFrontendFullname" . }} + minReplicas: {{ .Values.queryFrontend.autoscaling.minReplicas }} + maxReplicas: {{ .Values.queryFrontend.autoscaling.maxReplicas }} + metrics: + {{- with .Values.queryFrontend.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.queryFrontend.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.queryFrontend.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.queryFrontend.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.queryFrontend.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.queryFrontend.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/query-frontend/poddisruptionbudget-query-frontend.yaml b/charts/loki/templates/query-frontend/poddisruptionbudget-query-frontend.yaml new file mode 100644 index 0000000..f100405 --- /dev/null +++ b/charts/loki/templates/query-frontend/poddisruptionbudget-query-frontend.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.queryFrontend.replicas) 1) }} +{{- if kindIs "invalid" .Values.queryFrontend.maxUnavailable }} +{{- fail "`.Values.queryFrontend.maxUnavailable` must be set when `.Values.queryFrontend.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.queryFrontendFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.queryFrontendLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.queryFrontendSelectorLabels" . | nindent 6 }} + {{- with .Values.queryFrontend.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/query-frontend/service-query-frontend-headless.yaml b/charts/loki/templates/query-frontend/service-query-frontend-headless.yaml new file mode 100644 index 0000000..8da9054 --- /dev/null +++ b/charts/loki/templates/query-frontend/service-query-frontend-headless.yaml @@ -0,0 +1,46 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.queryFrontendFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.queryFrontendLabels" . | nindent 4 }} + {{- with .Values.queryFrontend.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.queryFrontend.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + type: ClusterIP + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.queryFrontend.appProtocol.grpc }} + appProtocol: {{ .Values.queryFrontend.appProtocol.grpc }} + {{- end }} + - name: grpclb + port: 9096 + targetPort: grpc + protocol: TCP + {{- if .Values.queryFrontend.appProtocol.grpc }} + appProtocol: {{ .Values.queryFrontend.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.queryFrontendSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/templates/query-frontend/service-query-frontend.yaml b/charts/loki/templates/query-frontend/service-query-frontend.yaml new file mode 100644 index 0000000..a239695 --- /dev/null +++ b/charts/loki/templates/query-frontend/service-query-frontend.yaml @@ -0,0 +1,44 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.queryFrontendFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.queryFrontendLabels" . | nindent 4 }} + {{- with .Values.queryFrontend.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.queryFrontend.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.queryFrontend.appProtocol.grpc }} + appProtocol: {{ .Values.queryFrontend.appProtocol.grpc }} + {{- end }} + - name: grpclb + port: 9096 + targetPort: grpc + protocol: TCP + {{- if .Values.queryFrontend.appProtocol.grpc }} + appProtocol: {{ .Values.queryFrontend.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.queryFrontendSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/loki/templates/query-scheduler/_helpers-query-scheduler.tpl b/charts/loki/templates/query-scheduler/_helpers-query-scheduler.tpl new file mode 100644 index 0000000..1f64802 --- /dev/null +++ b/charts/loki/templates/query-scheduler/_helpers-query-scheduler.tpl @@ -0,0 +1,40 @@ +{{/* +query-scheduler fullname +*/}} +{{- define "loki.querySchedulerFullname" -}} +{{ include "loki.fullname" . }}-query-scheduler +{{- end }} + +{{/* +query-scheduler common labels +*/}} +{{- define "loki.querySchedulerLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: query-scheduler +{{- end }} + +{{/* +query-scheduler selector labels +*/}} +{{- define "loki.querySchedulerSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: query-scheduler +{{- end }} + +{{/* +query-scheduler image +*/}} +{{- define "loki.querySchedulerImage" -}} +{{- $dict := dict "loki" .Values.loki.image "service" .Values.queryScheduler.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}} +{{- include "loki.lokiImage" $dict -}} +{{- end }} + +{{/* +query-scheduler priority class name +*/}} +{{- define "loki.querySchedulerPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.queryScheduler.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/query-scheduler/deployment-query-scheduler.yaml b/charts/loki/templates/query-scheduler/deployment-query-scheduler.yaml new file mode 100644 index 0000000..28dadaa --- /dev/null +++ b/charts/loki/templates/query-scheduler/deployment-query-scheduler.yaml @@ -0,0 +1,143 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.querySchedulerFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querySchedulerLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.queryScheduler.replicas }} + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.querySchedulerSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryScheduler.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.querySchedulerLabels" . | nindent 8 }} + {{- with merge (dict) .Values.loki.podLabels .Values.queryScheduler.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + app.kubernetes.io/part-of: memberlist + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.queryScheduler.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryScheduler.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.querySchedulerPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.queryScheduler.terminationGracePeriodSeconds }} + containers: + - name: query-scheduler + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=query-scheduler + {{- with (concat .Values.global.extraArgs .Values.queryScheduler.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.queryScheduler.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.queryScheduler.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + livenessProbe: + {{- toYaml .Values.loki.livenessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.queryScheduler.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.queryScheduler.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.queryScheduler.extraContainers }} + {{- toYaml .Values.queryScheduler.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.queryScheduler.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryScheduler.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryScheduler.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.queryScheduler.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/query-scheduler/poddisruptionbudget-query-scheduler.yaml b/charts/loki/templates/query-scheduler/poddisruptionbudget-query-scheduler.yaml new file mode 100644 index 0000000..ed8051f --- /dev/null +++ b/charts/loki/templates/query-scheduler/poddisruptionbudget-query-scheduler.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.queryScheduler.replicas) 1) }} +{{- if kindIs "invalid" .Values.queryScheduler.maxUnavailable }} +{{- fail "`.Values.queryScheduler.maxUnavailable` must be set when `.Values.queryScheduler.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.querySchedulerFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querySchedulerLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.querySchedulerSelectorLabels" . | nindent 6 }} + {{- with .Values.queryScheduler.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/query-scheduler/service-query-scheduler.yaml b/charts/loki/templates/query-scheduler/service-query-scheduler.yaml new file mode 100644 index 0000000..746c7bd --- /dev/null +++ b/charts/loki/templates/query-scheduler/service-query-scheduler.yaml @@ -0,0 +1,38 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.querySchedulerFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querySchedulerLabels" . | nindent 4 }} + {{- with .Values.queryScheduler.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.queryScheduler.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpclb + port: 9095 + targetPort: grpc + protocol: TCP + {{- with .Values.queryScheduler.appProtocol.grpc }} + appProtocol: {{ . }} + {{- end }} + selector: + {{- include "loki.querySchedulerSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/read/_helpers-read.tpl b/charts/loki/templates/read/_helpers-read.tpl new file mode 100644 index 0000000..d205314 --- /dev/null +++ b/charts/loki/templates/read/_helpers-read.tpl @@ -0,0 +1,32 @@ +{{/* +read fullname +*/}} +{{- define "loki.readFullname" -}} +{{ include "loki.name" . }}-read +{{- end }} + +{{/* +read common labels +*/}} +{{- define "loki.readLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: read +{{- end }} + +{{/* +read selector labels +*/}} +{{- define "loki.readSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: read +{{- end }} + +{{/* +read priority class name +*/}} +{{- define "loki.readPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.read.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/read/deployment-read.yaml b/charts/loki/templates/read/deployment-read.yaml new file mode 100644 index 0000000..f024a40 --- /dev/null +++ b/charts/loki/templates/read/deployment-read.yaml @@ -0,0 +1,163 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.readFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + app.kubernetes.io/part-of: memberlist + {{- include "loki.readLabels" . | nindent 4 }} + {{- if or (not (empty .Values.loki.annotations)) (not (empty .Values.backend.annotations))}} + annotations: + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.read.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + {{- if not .Values.read.autoscaling.enabled }} + replicas: {{ .Values.read.replicas }} + {{- end }} + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.readSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + app.kubernetes.io/part-of: memberlist + {{- include "loki.readSelectorLabels" . | nindent 8 }} + {{- with .Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.selectorLabels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.readPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.read.terminationGracePeriodSeconds }} + containers: + - name: loki + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target={{ .Values.read.targetModule }} + - -legacy-read-mode=false + - -common.compactor-grpc-address={{ include "loki.backendFullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:{{ .Values.loki.server.grpc_listen_port }} + {{- with .Values.read.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.loki.server.http_listen_port }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.loki.server.grpc_listen_port }} + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with .Values.read.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.read.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: tmp + mountPath: /tmp + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end}} + {{- with .Values.read.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.read.resources | nindent 12 }} + {{- with .Values.read.extraContainers }} + {{- toYaml . | nindent 8}} + {{- end }} + {{- with .Values.read.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.read.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: tmp + emptyDir: {} + - name: data + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with .Values.read.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/read/hpa.yaml b/charts/loki/templates/read/hpa.yaml new file mode 100644 index 0000000..5515ecb --- /dev/null +++ b/charts/loki/templates/read/hpa.yaml @@ -0,0 +1,55 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- $autoscalingv2 := .Capabilities.APIVersions.Has "autoscaling/v2" -}} +{{- if and $isSimpleScalable ( .Values.read.autoscaling.enabled ) }} +{{- if $autoscalingv2 }} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta1 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.readFullname" . }} + labels: + {{- include "loki.readLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }} + kind: Deployment + name: {{ include "loki.readFullname" . }} +{{- else }} + kind: StatefulSet + name: {{ include "loki.readFullname" . }} +{{- end }} + minReplicas: {{ .Values.read.autoscaling.minReplicas }} + maxReplicas: {{ .Values.read.autoscaling.maxReplicas }} + {{- with .Values.read.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} + metrics: + {{- with .Values.read.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.read.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/read/poddisruptionbudget-read.yaml b/charts/loki/templates/read/poddisruptionbudget-read.yaml new file mode 100644 index 0000000..af4fcbf --- /dev/null +++ b/charts/loki/templates/read/poddisruptionbudget-read.yaml @@ -0,0 +1,15 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (gt (int .Values.read.replicas) 1) }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.readFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.readLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.readSelectorLabels" . | nindent 6 }} + maxUnavailable: 1 +{{- end }} diff --git a/charts/loki/templates/read/service-read-headless.yaml b/charts/loki/templates/read/service-read-headless.yaml new file mode 100644 index 0000000..14ba0f6 --- /dev/null +++ b/charts/loki/templates/read/service-read-headless.yaml @@ -0,0 +1,41 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{ if $isSimpleScalable }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.readFullname" . }}-headless + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.readSelectorLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.read.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + variant: headless + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.read.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + appProtocol: tcp + selector: + {{- include "loki.readSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/read/service-read.yaml b/charts/loki/templates/read/service-read.yaml new file mode 100644 index 0000000..f4000fd --- /dev/null +++ b/charts/loki/templates/read/service-read.yaml @@ -0,0 +1,37 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isSimpleScalable }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.readFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.readLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.read.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.read.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + selector: + {{- include "loki.readSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/read/statefulset-read.yaml b/charts/loki/templates/read/statefulset-read.yaml new file mode 100644 index 0000000..e58ac6d --- /dev/null +++ b/charts/loki/templates/read/statefulset-read.yaml @@ -0,0 +1,194 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (.Values.read.legacyReadTarget ) }} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.readFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + app.kubernetes.io/part-of: memberlist + {{- include "loki.readLabels" . | nindent 4 }} + {{- if or (not (empty .Values.loki.annotations)) (not (empty .Values.read.annotations))}} + annotations: + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.read.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: +{{- if not .Values.read.autoscaling.enabled }} + {{- if eq .Values.deploymentMode "SingleBinary" }} + replicas: 0 + {{- else }} + replicas: {{ .Values.read.replicas }} + {{- end }} +{{- end }} + podManagementPolicy: {{ .Values.read.podManagementPolicy }} + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ printf "%s-headless" (include "loki.readFullname" .) }} + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.read.persistence.enableStatefulSetAutoDeletePVC) }} + {{/* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete + {{- end }} + selector: + matchLabels: + {{- include "loki.readSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + app.kubernetes.io/part-of: memberlist + {{- include "loki.readLabels" . | nindent 8 }} + {{- with merge (dict) .Values.loki.podLabels .Values.read.podLabels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{ include "loki.enableServiceLinks" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.readPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.read.terminationGracePeriodSeconds }} + containers: + - name: loki + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target={{ .Values.read.targetModule }} + {{- with (concat .Values.global.extraArgs .Values.read.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.loki.server.http_listen_port }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.loki.server.grpc_listen_port }} + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.read.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.read.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + {{- with .Values.read.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: tmp + mountPath: /tmp + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end}} + {{- with (concat .Values.global.extraVolumeMounts .Values.read.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.read.resources | nindent 12 }} + {{- with .Values.read.extraContainers }} + {{- toYaml . | nindent 8}} + {{- end }} + {{- with .Values.read.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.read.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: tmp + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.read.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + {{- with .Values.read.persistence.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.read.persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .Values.read.persistence.size | quote }} + {{- with .Values.read.persistence.selector }} + selector: + {{- toYaml . | nindent 10 }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/results-cache/poddisruptionbudget-results-cache.yaml b/charts/loki/templates/results-cache/poddisruptionbudget-results-cache.yaml new file mode 100644 index 0000000..6bc393a --- /dev/null +++ b/charts/loki/templates/results-cache/poddisruptionbudget-results-cache.yaml @@ -0,0 +1,16 @@ +{{- if .Values.resultsCache.enabled }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.fullname" . }}-memcached-results-cache + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: memcached-results-cache +spec: + selector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: memcached-results-cache + maxUnavailable: 1 +{{- end -}} diff --git a/charts/loki/templates/results-cache/service-results-cache-headless.yaml b/charts/loki/templates/results-cache/service-results-cache-headless.yaml new file mode 100644 index 0000000..ce92008 --- /dev/null +++ b/charts/loki/templates/results-cache/service-results-cache-headless.yaml @@ -0,0 +1 @@ +{{- include "loki.memcached.service" (dict "ctx" $ "valuesSection" "resultsCache" "component" "results-cache" ) }} diff --git a/charts/loki/templates/results-cache/statefulset-results-cache.yaml b/charts/loki/templates/results-cache/statefulset-results-cache.yaml new file mode 100644 index 0000000..042e74e --- /dev/null +++ b/charts/loki/templates/results-cache/statefulset-results-cache.yaml @@ -0,0 +1 @@ +{{- include "loki.memcached.statefulSet" (dict "ctx" $ "valuesSection" "resultsCache" "component" "results-cache" ) }} diff --git a/charts/loki/templates/role.yaml b/charts/loki/templates/role.yaml new file mode 100644 index 0000000..1e714b6 --- /dev/null +++ b/charts/loki/templates/role.yaml @@ -0,0 +1,36 @@ +{{- if or .Values.rbac.pspEnabled .Values.rbac.sccEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "loki.name" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +{{- if .Values.rbac.pspEnabled }} +rules: + - apiGroups: + - policy + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ include "loki.name" . }} +{{- end }} +{{- if .Values.rbac.sccEnabled }} +rules: + - apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + verbs: + - use + resourceNames: + - {{ include "loki.name" . }} + {{- if and .Values.rbac.namespaced .Values.sidecar.rules.enabled }} + - apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/rolebinding.yaml b/charts/loki/templates/rolebinding.yaml new file mode 100644 index 0000000..cc0dfd2 --- /dev/null +++ b/charts/loki/templates/rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if or .Values.rbac.pspEnabled .Values.rbac.sccEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "loki.name" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "loki.name" . }} +subjects: + - kind: ServiceAccount + name: {{ include "loki.serviceAccountName" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} diff --git a/charts/loki/templates/ruler/_helpers-ruler.tpl b/charts/loki/templates/ruler/_helpers-ruler.tpl new file mode 100644 index 0000000..2079e03 --- /dev/null +++ b/charts/loki/templates/ruler/_helpers-ruler.tpl @@ -0,0 +1,47 @@ +{{/* +ruler fullname +*/}} +{{- define "loki.rulerFullname" -}} +{{ include "loki.fullname" . }}-ruler +{{- end }} + +{{/* +ruler common labels +*/}} +{{- define "loki.rulerLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: ruler +{{- end }} + +{{/* +ruler selector labels +*/}} +{{- define "loki.rulerSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: ruler +{{- end }} + +{{/* +ruler image +*/}} +{{- define "loki.rulerImage" -}} +{{- $dict := dict "loki" .Values.loki.image "service" .Values.ruler.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}} +{{- include "loki.lokiImage" $dict -}} +{{- end }} + +{{/* +format rules dir +*/}} +{{- define "loki.rulerRulesDirName" -}} +rules-{{ . | replace "_" "-" | trimSuffix "-" | lower }} +{{- end }} + +{{/* +ruler priority class name +*/}} +{{- define "loki.rulerPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.ruler.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/ruler/configmap-ruler.yaml b/charts/loki/templates/ruler/configmap-ruler.yaml new file mode 100644 index 0000000..3a0c533 --- /dev/null +++ b/charts/loki/templates/ruler/configmap-ruler.yaml @@ -0,0 +1,15 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +{{- range $dir, $files := .Values.ruler.directories }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "loki.rulerFullname" $ }}-{{ include "loki.rulerRulesDirName" $dir }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.rulerLabels" $ | nindent 4 }} +data: + {{- toYaml $files | nindent 2}} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/ruler/poddisruptionbudget-ruler.yaml b/charts/loki/templates/ruler/poddisruptionbudget-ruler.yaml new file mode 100644 index 0000000..b9c03cf --- /dev/null +++ b/charts/loki/templates/ruler/poddisruptionbudget-ruler.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.ruler.replicas) 1) }} +{{- if kindIs "invalid" .Values.ruler.maxUnavailable }} +{{- fail "`.Values.ruler.maxUnavailable` must be set when `.Values.ruler.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.rulerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.rulerLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.rulerSelectorLabels" . | nindent 6 }} + {{- with .Values.ruler.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/ruler/service-ruler.yaml b/charts/loki/templates/ruler/service-ruler.yaml new file mode 100644 index 0000000..8847683 --- /dev/null +++ b/charts/loki/templates/ruler/service-ruler.yaml @@ -0,0 +1,37 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ruler.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.rulerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.rulerSelectorLabels" . | nindent 4 }} + {{- with .Values.ruler.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.ruler.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- with .Values.ruler.appProtocol.grpc }} + appProtocol: {{ . }} + {{- end }} + selector: + {{- include "loki.rulerSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/ruler/statefulset-ruler.yaml b/charts/loki/templates/ruler/statefulset-ruler.yaml new file mode 100644 index 0000000..20b53a4 --- /dev/null +++ b/charts/loki/templates/ruler/statefulset-ruler.yaml @@ -0,0 +1,183 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ruler.enabled }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.rulerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.rulerLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.ruler.replicas }} + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + serviceName: {{ include "loki.rulerFullname" . }} + selector: + matchLabels: + {{- include "loki.rulerSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ruler.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.rulerLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.ruler.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.ruler.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ruler.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.rulerPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.ruler.terminationGracePeriodSeconds }} + {{- with .Values.ruler.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: ruler + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=ruler + {{- with (concat .Values.global.extraArgs .Values.ruler.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.ruler.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.ruler.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + - name: tmp + mountPath: /tmp/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- range $dir, $_ := .Values.ruler.directories }} + - name: {{ include "loki.rulerRulesDirName" $dir }} + mountPath: /etc/loki/rules/{{ $dir }} + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.ruler.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.ruler.resources | nindent 12 }} + {{- with .Values.ruler.extraContainers }} + {{- toYaml . | nindent 8}} + {{- end }} + {{- with .Values.ruler.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ruler.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ruler.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ruler.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- range $dir, $_ := .Values.ruler.directories }} + - name: {{ include "loki.rulerRulesDirName" $dir }} + configMap: + name: {{ include "loki.rulerFullname" $ }}-{{ include "loki.rulerRulesDirName" $dir }} + {{- end }} + - name: tmp + emptyDir: {} + {{- with (concat .Values.global.extraVolumes .Values.ruler.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.ruler.persistence.enabled }} + - name: data + emptyDir: {} + {{- else }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + {{- with .Values.ruler.persistence.annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.ruler.persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .Values.ruler.persistence.size | quote }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/runtime-configmap.yaml b/charts/loki/templates/runtime-configmap.yaml new file mode 100644 index 0000000..2f38193 --- /dev/null +++ b/charts/loki/templates/runtime-configmap.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "loki.name" . }}-runtime + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +data: + runtime-config.yaml: | + {{- tpl (toYaml .Values.loki.runtimeConfig) . | nindent 4 }} diff --git a/charts/loki/templates/secret-license.yaml b/charts/loki/templates/secret-license.yaml new file mode 100644 index 0000000..eaa519f --- /dev/null +++ b/charts/loki/templates/secret-license.yaml @@ -0,0 +1,11 @@ +{{- if and (not .Values.enterprise.useExternalLicense) .Values.enterprise.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: enterprise-logs-license + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +data: + license.jwt: {{ .Values.enterprise.license.contents | b64enc }} +{{- end }} diff --git a/charts/loki/templates/securitycontextconstraints.yaml b/charts/loki/templates/securitycontextconstraints.yaml new file mode 100644 index 0000000..c3a604d --- /dev/null +++ b/charts/loki/templates/securitycontextconstraints.yaml @@ -0,0 +1,40 @@ +{{- if .Values.rbac.sccEnabled }} +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: {{ include "loki.name" . }} + labels: + {{- include "loki.labels" . | nindent 4 }} +allowHostDirVolumePlugin: false +allowHostIPC: false +allowHostNetwork: false +allowHostPID: false +allowHostPorts: false +allowPrivilegeEscalation: true +allowPrivilegedContainer: false +allowedCapabilities: [] +defaultAddCapabilities: null +fsGroup: + type: RunAsAny +groups: [] +priority: null +readOnlyRootFilesystem: false +requiredDropCapabilities: + - ALL +runAsUser: + type: RunAsAny +seLinuxContext: + type: MustRunAs +seccompProfiles: + - '*' +supplementalGroups: + type: RunAsAny +volumes: + - configMap + - downwardAPI + - emptyDir + - hostPath + - persistentVolumeClaim + - projected + - secret +{{- end }} diff --git a/charts/loki/templates/service-memberlist.yaml b/charts/loki/templates/service-memberlist.yaml new file mode 100644 index 0000000..3d46f23 --- /dev/null +++ b/charts/loki/templates/service-memberlist.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.memberlist" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.memberlist.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: tcp + port: 7946 + targetPort: http-memberlist + protocol: TCP + {{- with .Values.memberlist.service.publishNotReadyAddresses }} + publishNotReadyAddresses: {{ . }} + {{- end }} + selector: + {{- include "loki.selectorLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist diff --git a/charts/loki/templates/serviceaccount.yaml b/charts/loki/templates/serviceaccount.yaml new file mode 100644 index 0000000..dd89141 --- /dev/null +++ b/charts/loki/templates/serviceaccount.yaml @@ -0,0 +1,21 @@ +{{ if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "loki.serviceAccountName" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- tpl (toYaml . | nindent 4) $ }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- with .Values.serviceAccount.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/single-binary/_helpers-single-binary.tpl b/charts/loki/templates/single-binary/_helpers-single-binary.tpl new file mode 100644 index 0000000..4ea3c6d --- /dev/null +++ b/charts/loki/templates/single-binary/_helpers-single-binary.tpl @@ -0,0 +1,34 @@ +{{/* +singleBinary common labels +*/}} +{{- define "loki.singleBinaryLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: single-binary +{{- end }} + + +{{/* singleBinary selector labels */}} +{{- define "loki.singleBinarySelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: single-binary +{{- end }} + +{{/* +singleBinary priority class name +*/}} +{{- define "loki.singleBinaryPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.singleBinary.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} + +{{/* singleBinary replicas calculation */}} +{{- define "loki.singleBinaryReplicas" -}} +{{- $replicas := 1 }} +{{- $usingObjectStorage := eq (include "loki.isUsingObjectStorage" .) "true" }} +{{- if and $usingObjectStorage (gt (int .Values.singleBinary.replicas) 1)}} +{{- $replicas = int .Values.singleBinary.replicas -}} +{{- end }} +{{- printf "%d" $replicas }} +{{- end }} diff --git a/charts/loki/templates/single-binary/hpa.yaml b/charts/loki/templates/single-binary/hpa.yaml new file mode 100644 index 0000000..c529f18 --- /dev/null +++ b/charts/loki/templates/single-binary/hpa.yaml @@ -0,0 +1,51 @@ +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- $usingObjectStorage := eq (include "loki.isUsingObjectStorage" .) "true" }} +{{- $autoscalingv2 := .Capabilities.APIVersions.Has "autoscaling/v2" -}} +{{- if and $isSingleBinary $usingObjectStorage ( .Values.singleBinary.autoscaling.enabled ) }} +{{- if $autoscalingv2 }} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta1 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.singleBinaryFullname" . }} + labels: + {{- include "loki.singleBinaryLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.singleBinaryFullname" . }} + minReplicas: {{ .Values.singleBinary.autoscaling.minReplicas }} + maxReplicas: {{ .Values.singleBinary.autoscaling.maxReplicas }} + {{- with .Values.singleBinary.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} + metrics: + {{- with .Values.singleBinary.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.singleBinary.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/single-binary/pdb.yaml b/charts/loki/templates/single-binary/pdb.yaml new file mode 100644 index 0000000..bb1e1cc --- /dev/null +++ b/charts/loki/templates/single-binary/pdb.yaml @@ -0,0 +1,16 @@ +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- if and .Values.podDisruptionBudget $isSingleBinary -}} +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.singleBinarySelectorLabels" . | nindent 6 }} +{{ toYaml .Values.podDisruptionBudget | indent 2 }} +{{- end }} diff --git a/charts/loki/templates/single-binary/service-headless.yaml b/charts/loki/templates/single-binary/service-headless.yaml new file mode 100644 index 0000000..7522240 --- /dev/null +++ b/charts/loki/templates/single-binary/service-headless.yaml @@ -0,0 +1,35 @@ +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- if $isSingleBinary }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.name" . }}-headless + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.singleBinary.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + variant: headless + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.singleBinary.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + selector: + {{- include "loki.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/single-binary/service.yaml b/charts/loki/templates/single-binary/service.yaml new file mode 100644 index 0000000..352fcad --- /dev/null +++ b/charts/loki/templates/single-binary/service.yaml @@ -0,0 +1,40 @@ +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- if $isSingleBinary }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.singleBinaryFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.singleBinary.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.singleBinary.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + selector: + {{- include "loki.singleBinarySelectorLabels" . | nindent 4 }} + {{- with .Values.singleBinary.selectorLabels }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/single-binary/statefulset.yaml b/charts/loki/templates/single-binary/statefulset.yaml new file mode 100644 index 0000000..54f3d92 --- /dev/null +++ b/charts/loki/templates/single-binary/statefulset.yaml @@ -0,0 +1,278 @@ +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- if $isSingleBinary }} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.singleBinaryFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.singleBinaryLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- if or (not (empty .Values.loki.annotations)) (not (empty .Values.singleBinary.annotations))}} + annotations: + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.singleBinary.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + replicas: {{ include "loki.singleBinaryReplicas" . }} + podManagementPolicy: Parallel + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.singleBinaryFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.singleBinary.persistence.enableStatefulSetAutoDeletePVC) (.Values.singleBinary.persistence.enabled) }} + {{/* + Data on the singleBinary nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete + {{- end }} + selector: + matchLabels: + {{- include "loki.singleBinarySelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.singleBinarySelectorLabels" . | nindent 8 }} + {{- with .Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.selectorLabels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + app.kubernetes.io/part-of: memberlist + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{ include "loki.enableServiceLinks" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.singleBinaryPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.singleBinary.terminationGracePeriodSeconds }} + {{- if .Values.singleBinary.initContainers }} + initContainers: + {{- with .Values.singleBinary.initContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + containers: + {{- if .Values.sidecar.rules.enabled }} + - name: loki-sc-rules + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.image.pullPolicy }} + env: + - name: METHOD + value: {{ .Values.sidecar.rules.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.rules.label }}" + {{- if .Values.sidecar.rules.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.rules.labelValue }} + {{- end }} + - name: FOLDER + value: "{{ .Values.sidecar.rules.folder }}" + - name: RESOURCE + value: {{ quote .Values.sidecar.rules.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.rules.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.rules.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + {{- if .Values.sidecar.rules.script }} + - name: SCRIPT + value: "{{ .Values.sidecar.rules.script }}" + {{- end }} + {{- if .Values.sidecar.rules.watchServerTimeout }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.rules.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.rules.watchClientTimeout }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.rules.watchClientTimeout }}" + {{- end }} + {{- if .Values.sidecar.rules.logLevel }} + - name: LOG_LEVEL + value: "{{ .Values.sidecar.rules.logLevel }}" + {{- end }} + {{- if .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml .Values.sidecar.livenessProbe | nindent 12 }} + {{- end }} + {{- if .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml .Values.sidecar.readinessProbe | nindent 12 }} + {{- end }} + {{- if .Values.sidecar.resources }} + resources: + {{- toYaml .Values.sidecar.resources | nindent 12 }} + {{- end }} + {{- if .Values.sidecar.securityContext }} + securityContext: + {{- toYaml .Values.sidecar.securityContext | nindent 12 }} + {{- end }} + volumeMounts: + - name: sc-rules-volume + mountPath: {{ .Values.sidecar.rules.folder | quote }} + {{- end}} + - name: loki + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target={{ .Values.singleBinary.targetModule }} + {{- with .Values.singleBinary.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.loki.server.http_listen_port }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.loki.server.grpc_listen_port }} + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with .Values.singleBinary.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.singleBinary.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + {{- if .Values.singleBinary.persistence.enabled }} + - name: storage + mountPath: /var/loki + {{- end }} + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- if .Values.sidecar.rules.enabled }} + - name: sc-rules-volume + mountPath: {{ .Values.sidecar.rules.folder | quote }} + {{- end}} + {{- with .Values.singleBinary.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.singleBinary.resources | nindent 12 }} + {{- with .Values.singleBinary.extraContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: tmp + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- if .Values.sidecar.rules.enabled }} + - name: sc-rules-volume + {{- if .Values.sidecar.rules.sizeLimit }} + emptyDir: + sizeLimit: {{ .Values.sidecar.rules.sizeLimit }} + {{- else }} + emptyDir: {} + {{- end -}} + {{- end -}} + {{- with .Values.singleBinary.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.singleBinary.persistence.enabled }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: storage + {{- with .Values.singleBinary.persistence.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.singleBinary.persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .Values.singleBinary.persistence.size | quote }} + {{- with .Values.singleBinary.persistence.selector }} + selector: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/table-manager/_helpers-table-manager.tpl b/charts/loki/templates/table-manager/_helpers-table-manager.tpl new file mode 100644 index 0000000..ff25832 --- /dev/null +++ b/charts/loki/templates/table-manager/_helpers-table-manager.tpl @@ -0,0 +1,32 @@ +{{/* +table-manager fullname +*/}} +{{- define "loki.tableManagerFullname" -}} +{{ include "loki.fullname" . }}-table-manager +{{- end }} + +{{/* +table-manager common labels +*/}} +{{- define "loki.tableManagerLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: table-manager +{{- end }} + +{{/* +table-manager selector labels +*/}} +{{- define "loki.tableManagerSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: table-manager +{{- end }} + +{{/* +table-manager priority class name +*/}} +{{- define "loki.tableManagerPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.tableManager.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/table-manager/deployment-table-manager.yaml b/charts/loki/templates/table-manager/deployment-table-manager.yaml new file mode 100644 index 0000000..770629b --- /dev/null +++ b/charts/loki/templates/table-manager/deployment-table-manager.yaml @@ -0,0 +1,126 @@ +{{- if .Values.tableManager.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.tableManagerFullname" . }} + labels: + {{- include "loki.tableManagerLabels" . | nindent 4 }} + annotations: + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.tableManager.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.tableManagerSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tableManager.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.tableManagerSelectorLabels" . | nindent 8 }} + {{- with .Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tableManager.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.tableManagerPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.tableManager.terminationGracePeriodSeconds }} + containers: + - name: table-manager + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=table-manager + {{- with .Values.tableManager.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.loki.server.http_listen_port }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.loki.server.grpc_listen_port }} + protocol: TCP + {{- with .Values.tableManager.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.tableManager.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + livenessProbe: + {{- toYaml .Values.loki.livenessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with .Values.tableManager.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.tableManager.resources | nindent 12 }} + {{- if .Values.tableManager.extraContainers }} + {{- toYaml .Values.tableManager.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.tableManager.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tableManager.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.tableManager.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tableManager.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with .Values.tableManager.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/table-manager/service-table-manager.yaml b/charts/loki/templates/table-manager/service-table-manager.yaml new file mode 100644 index 0000000..214cd36 --- /dev/null +++ b/charts/loki/templates/table-manager/service-table-manager.yaml @@ -0,0 +1,36 @@ +{{- if .Values.tableManager.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.fullname" . }}-table-manager + labels: + {{- include "loki.labels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.tableManager.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + app.kubernetes.io/component: table-manager + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.tableManager.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + selector: + {{- include "loki.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: table-manager +{{- end }} diff --git a/charts/loki/templates/table-manager/servicemonitor-table-manager.yaml b/charts/loki/templates/table-manager/servicemonitor-table-manager.yaml new file mode 100644 index 0000000..09aa727 --- /dev/null +++ b/charts/loki/templates/table-manager/servicemonitor-table-manager.yaml @@ -0,0 +1,57 @@ +{{- if .Values.tableManager.enabled }} +{{- with .Values.serviceMonitor }} +{{- if .enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "loki.tableManagerFullname" $ }} + {{- with .namespace }} + namespace: {{ . }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "loki.tableManagerLabels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- include "loki.tableManagerSelectorLabels" $ | nindent 6 }} + endpoints: + - port: http-metrics + {{- with .interval }} + interval: {{ . }} + {{- end }} + {{- with .scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .scheme }} + scheme: {{ . }} + {{- end }} + {{- with .tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .targetLabels }} + targetLabels: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/tests/_helpers.tpl b/charts/loki/templates/tests/_helpers.tpl new file mode 100644 index 0000000..9ef7c15 --- /dev/null +++ b/charts/loki/templates/tests/_helpers.tpl @@ -0,0 +1,16 @@ +{{/* +Docker image name for loki helm test +*/}} +{{- define "loki.helmTestImage" -}} +{{- $dict := dict "service" .Values.test.image "global" .Values.global.image "defaultVersion" "latest" -}} +{{- include "loki.baseImage" $dict -}} +{{- end -}} + + +{{/* +test common labels +*/}} +{{- define "loki.helmTestLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: helm-test +{{- end }} diff --git a/charts/loki/templates/tests/test-canary.yaml b/charts/loki/templates/tests/test-canary.yaml new file mode 100644 index 0000000..4d99228 --- /dev/null +++ b/charts/loki/templates/tests/test-canary.yaml @@ -0,0 +1,36 @@ +{{- with .Values.test }} +{{- if (and .enabled $.Values.lokiCanary.enabled) }} +--- +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "loki.name" $ }}-helm-test" + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.helmTestLabels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": test +spec: + containers: + - name: loki-helm-test + image: {{ include "loki.helmTestImage" $ }} + env: + - name: CANARY_SERVICE_ADDRESS + value: "{{ .canaryServiceAddress }}" + - name: CANARY_PROMETHEUS_ADDRESS + value: "{{ .prometheusAddress }}" + {{- with .timeout }} + - name: CANARY_TEST_TIMEOUT + value: "{{ . }}" + {{- end }} + args: + - -test.v + restartPolicy: Never +{{- end }} +{{- end }} diff --git a/charts/loki/templates/tokengen/_helpers.yaml b/charts/loki/templates/tokengen/_helpers.yaml new file mode 100644 index 0000000..3c881f2 --- /dev/null +++ b/charts/loki/templates/tokengen/_helpers.yaml @@ -0,0 +1,22 @@ +{{/* +tokengen fullname +*/}} +{{- define "enterprise-logs.tokengenFullname" -}} +{{ include "loki.name" . }}-tokengen +{{- end }} + +{{/* +tokengen common labels +*/}} +{{- define "enterprise-logs.tokengenLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: tokengen +{{- end }} + +{{/* +tokengen selector labels +*/}} +{{- define "enterprise-logs.tokengenSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: tokengen +{{- end }} diff --git a/charts/loki/templates/tokengen/clusterrole-tokengen.yaml b/charts/loki/templates/tokengen/clusterrole-tokengen.yaml new file mode 100644 index 0000000..d357622 --- /dev/null +++ b/charts/loki/templates/tokengen/clusterrole-tokengen.yaml @@ -0,0 +1,21 @@ +{{ if and .Values.enterprise.tokengen.enabled .Values.enterprise.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ if not .Values.rbac.namespaced }}Cluster{{ end }}Role +metadata: + name: {{ template "enterprise-logs.tokengenFullname" . }} + labels: + {{- include "enterprise-logs.tokengenLabels" . | nindent 4 }} + {{- with .Values.enterprise.tokengen.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.tokengen.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["create", "get", "patch"] +{{- end }} diff --git a/charts/loki/templates/tokengen/clusterrolebinding-tokengen.yaml b/charts/loki/templates/tokengen/clusterrolebinding-tokengen.yaml new file mode 100644 index 0000000..fb21d8f --- /dev/null +++ b/charts/loki/templates/tokengen/clusterrolebinding-tokengen.yaml @@ -0,0 +1,25 @@ +{{ if and .Values.enterprise.tokengen.enabled .Values.enterprise.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ if not .Values.rbac.namespaced }}Cluster{{ end }}RoleBinding +metadata: + name: {{ template "enterprise-logs.tokengenFullname" . }} + labels: + {{- include "enterprise-logs.tokengenLabels" . | nindent 4 }} + {{- with .Values.enterprise.tokengen.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.tokengen.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: {{ if not .Values.rbac.namespaced }}Cluster{{ end }}Role + name: {{ template "enterprise-logs.tokengenFullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "enterprise-logs.tokengenFullname" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} diff --git a/charts/loki/templates/tokengen/job-tokengen.yaml b/charts/loki/templates/tokengen/job-tokengen.yaml new file mode 100644 index 0000000..b0950d6 --- /dev/null +++ b/charts/loki/templates/tokengen/job-tokengen.yaml @@ -0,0 +1,143 @@ +{{ if and .Values.enterprise.tokengen.enabled .Values.enterprise.enabled }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "enterprise-logs.tokengenFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "enterprise-logs.tokengenLabels" . | nindent 4 }} + {{- with .Values.enterprise.tokengen.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.tokengen.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install + "helm.sh/hook-weight": "10" +spec: + backoffLimit: 6 + completions: 1 + parallelism: 1 + template: + metadata: + labels: + {{- include "enterprise-logs.tokengenSelectorLabels" . | nindent 8 }} + {{- with .Values.enterprise.tokengen.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{- with .Values.enterprise.tokengen.annotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.enterprise.tokengen.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + securityContext: + {{- toYaml .Values.enterprise.tokengen.securityContext | nindent 8 }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + initContainers: + - name: loki + image: {{ template "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + # The shared emptyDir exists only while the job is running, and is deleted once the job is completed. + # The tokengen generates a new admin token in case the 'token-file' file doesn't exist. + # As a result, subsequent executions of this tokengen job will generate new admin tokens. + # Note that previously generated tokens remain valid, as these remain present in the object storage. + - -config.file=/etc/loki/config/config.yaml + - -target={{ .Values.enterprise.tokengen.targetModule }} + - -tokengen.token-file=/shared/admin-token + {{- with .Values.enterprise.tokengen.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.enterprise.tokengen.extraVolumeMounts }} + {{ toYaml .Values.enterprise.tokengen.extraVolumeMounts | nindent 12 }} + {{- end }} + - name: shared + mountPath: /shared + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: license + mountPath: /etc/loki/license + env: + {{- if .Values.enterprise.tokengen.env }} + {{ toYaml .Values.enterprise.tokengen.env | nindent 12 }} + {{- end }} + {{- with .Values.enterprise.tokengen.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + containers: + - name: create-secret + image: {{ include "loki.kubectlImage" . }} + imagePullPolicy: {{ .Values.kubectlImage.pullPolicy }} + command: + - /bin/bash + - -euc + - | + # Create or update admin token secrets generated by tokengen job + kubectl create secret generic "{{ include "enterprise-logs.adminTokenSecret" . }}" \ + --from-file=token=/shared/admin-token \ + --dry-run=client -o yaml \ + | kubectl apply -f - + {{- with .Values.enterprise.adminToken.additionalNamespaces }} + {{- range . }} + kubectl --namespace "{{ . }}" create secret generic "{{ include "enterprise-logs.adminTokenSecret" $ }}" \ + --from-file=token=/shared/admin-token \ + --dry-run=client -o yaml \ + | kubectl apply -f - + {{- end }} + {{- end }} + volumeMounts: + {{- if .Values.enterprise.tokengen.extraVolumeMounts }} + {{ toYaml .Values.enterprise.tokengen.extraVolumeMounts | nindent 12 }} + {{- end }} + - name: shared + mountPath: /shared + - name: config + mountPath: /etc/loki/config + - name: license + mountPath: /etc/loki/license + restartPolicy: OnFailure + serviceAccount: {{ template "enterprise-logs.tokengenFullname" . }} + serviceAccountName: {{ template "enterprise-logs.tokengenFullname" . }} + {{- with .Values.enterprise.tokengen.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.enterprise.tokengen.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.enterprise.tokengen.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + - name: shared + emptyDir: {} + {{- if .Values.enterprise.tokengen.extraVolumes }} + {{ toYaml .Values.enterprise.tokengen.extraVolumes | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/tokengen/serviceaccount-tokengen.yaml b/charts/loki/templates/tokengen/serviceaccount-tokengen.yaml new file mode 100644 index 0000000..6f0e5a3 --- /dev/null +++ b/charts/loki/templates/tokengen/serviceaccount-tokengen.yaml @@ -0,0 +1,18 @@ +{{ if and .Values.enterprise.tokengen.enabled .Values.enterprise.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "enterprise-logs.tokengenFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "enterprise-logs.tokengenLabels" . | nindent 4 }} + {{- with .Values.enterprise.tokengen.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.tokengen.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install +{{- end }} diff --git a/charts/loki/templates/validate.yaml b/charts/loki/templates/validate.yaml new file mode 100644 index 0000000..93e2490 --- /dev/null +++ b/charts/loki/templates/validate.yaml @@ -0,0 +1,41 @@ +{{- if .Values.config }} +{{- fail "Top level 'config' is not allowed. Most common configuration sections are exposed under the `loki` section. If you need to override the whole config, provide the configuration as a string that can contain template expressions under `loki.config`. Alternatively, you can provide the configuration as an external secret." }} +{{- end }} + +{{- if and (not .Values.lokiCanary.enabled) .Values.test.enabled }} +{{- fail "Helm test requires the Loki Canary to be enabled"}} +{{- end }} + +{{- $singleBinaryReplicas := int .Values.singleBinary.replicas }} +{{- $isUsingFilesystem := eq (include "loki.isUsingObjectStorage" .) "false" }} +{{- $atLeastOneScalableReplica := or (gt (int .Values.backend.replicas) 0) (gt (int .Values.read.replicas) 0) (gt (int .Values.write.replicas) 0) }} +{{- $atLeastOneDistributedReplica := or (gt (int .Values.ingester.replicas) 0) (gt (int .Values.distributor.replicas) 0) (gt (int .Values.querier.replicas) 0) (gt (int .Values.queryFrontend.replicas) 0) (gt (int .Values.queryScheduler.replicas) 0) (gt (int .Values.indexGateway.replicas) 0) (gt (int .Values.compactor.replicas) 0) (gt (int .Values.ruler.replicas) 0) }} + +{{- if and $isUsingFilesystem (gt $singleBinaryReplicas 1) }} +{{- fail "Cannot run more than 1 Single Binary replica without an object storage backend."}} +{{- end }} + +{{- if and $isUsingFilesystem (and (eq $singleBinaryReplicas 0) (or $atLeastOneScalableReplica $atLeastOneDistributedReplica)) }} +{{- fail "Cannot run scalable targets (backend, read, write) or distributed targets without an object storage backend."}} +{{- end }} + +{{- if and $atLeastOneScalableReplica $atLeastOneDistributedReplica (ne .Values.deploymentMode "SimpleScalable<->Distributed") }} +{{- fail "You have more than zero replicas configured for scalable targets (backend, read, write) and distributed targets. If this was intentional change the deploymentMode to the transitional 'SimpleScalable<->Distributed' mode" }} +{{- end }} + +{{- if and (gt $singleBinaryReplicas 0) $atLeastOneDistributedReplica }} +{{- fail "You have more than zero replicas configured for both the single binary and distributed targets, there is no transition mode between these targets please change one or the other to zero or transition to the SimpleScalable mode first."}} +{{- end }} + +{{- if and (gt $singleBinaryReplicas 0) $atLeastOneScalableReplica (ne .Values.deploymentMode "SingleBinary<->SimpleScalable") }} +{{- fail "You have more than zero replicas configured for both the single binary and simple scalable targets. If this was intentional change the deploymentMode to the transitional 'SingleBinary<->SimpleScalable' mode"}} +{{- end }} + +{{- if and (or (not (empty .Values.loki.schemaConfig)) (not (empty .Values.loki.structuredConfig.schema_config))) .Values.loki.useTestSchema }} +{{- fail "loki.useTestSchema must be false if loki.schemaConfig or loki.structuredConfig.schema_config are defined."}} +{{- end }} + + +{{- if and (empty .Values.loki.schemaConfig) (empty .Values.loki.structuredConfig.schema_config) (not .Values.loki.useTestSchema) }} +{{- fail "You must provide a schema_config for Loki, one is not provided as this will be individual for every Loki cluster. See https://grafana.com/docs/loki/latest/operations/storage/schema/ for schema information. For quick testing (with no persistence) add `--set loki.useTestSchema=true`"}} +{{- end }} \ No newline at end of file diff --git a/charts/loki/templates/write/_helpers-write.tpl b/charts/loki/templates/write/_helpers-write.tpl new file mode 100644 index 0000000..8f526bc --- /dev/null +++ b/charts/loki/templates/write/_helpers-write.tpl @@ -0,0 +1,32 @@ +{{/* +write fullname +*/}} +{{- define "loki.writeFullname" -}} +{{ include "loki.name" . }}-write +{{- end }} + +{{/* +write common labels +*/}} +{{- define "loki.writeLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: write +{{- end }} + +{{/* +write selector labels +*/}} +{{- define "loki.writeSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: write +{{- end }} + +{{/* +write priority class name +*/}} +{{- define "loki.writePriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.write.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/write/hpa.yaml b/charts/loki/templates/write/hpa.yaml new file mode 100644 index 0000000..ba88ee2 --- /dev/null +++ b/charts/loki/templates/write/hpa.yaml @@ -0,0 +1,51 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- $autoscalingv2 := .Capabilities.APIVersions.Has "autoscaling/v2" -}} +{{- if and $isSimpleScalable ( .Values.write.autoscaling.enabled ) }} +{{- if $autoscalingv2 }} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta1 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.writeFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.writeLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.writeFullname" . }} + minReplicas: {{ .Values.write.autoscaling.minReplicas }} + maxReplicas: {{ .Values.write.autoscaling.maxReplicas }} + {{- with .Values.write.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} + metrics: + {{- with .Values.write.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.write.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/templates/write/poddisruptionbudget-write.yaml b/charts/loki/templates/write/poddisruptionbudget-write.yaml new file mode 100644 index 0000000..24e1356 --- /dev/null +++ b/charts/loki/templates/write/poddisruptionbudget-write.yaml @@ -0,0 +1,15 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (gt (int .Values.write.replicas) 1) }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.writeFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.writeLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.writeSelectorLabels" . | nindent 6 }} + maxUnavailable: 1 +{{- end }} diff --git a/charts/loki/templates/write/service-write-headless.yaml b/charts/loki/templates/write/service-write-headless.yaml new file mode 100644 index 0000000..84cf5d7 --- /dev/null +++ b/charts/loki/templates/write/service-write-headless.yaml @@ -0,0 +1,41 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isSimpleScalable }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.writeFullname" . }}-headless + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.writeSelectorLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.write.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + variant: headless + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.write.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + appProtocol: tcp + selector: + {{- include "loki.writeSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/write/service-write.yaml b/charts/loki/templates/write/service-write.yaml new file mode 100644 index 0000000..9603706 --- /dev/null +++ b/charts/loki/templates/write/service-write.yaml @@ -0,0 +1,37 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isSimpleScalable }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.writeFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.writeLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.write.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.write.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + selector: + {{- include "loki.writeSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/loki/templates/write/statefulset-write.yaml b/charts/loki/templates/write/statefulset-write.yaml new file mode 100644 index 0000000..97a0818 --- /dev/null +++ b/charts/loki/templates/write/statefulset-write.yaml @@ -0,0 +1,211 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isSimpleScalable }} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.writeFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.writeLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- if or (not (empty .Values.loki.annotations)) (not (empty .Values.backend.annotations))}} + annotations: + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.write.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: +{{- if not .Values.write.autoscaling.enabled }} + {{- if eq .Values.deploymentMode "SingleBinary" }} + replicas: 0 + {{- else }} + replicas: {{ .Values.write.replicas }} + {{- end }} +{{- end }} + podManagementPolicy: {{ .Values.write.podManagementPolicy }} + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.writeFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.write.persistence.enableStatefulSetAutoDeletePVC) (.Values.write.persistence.volumeClaimsEnabled) }} + {{/* + Data on the write nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete + {{- end }} + selector: + matchLabels: + {{- include "loki.writeSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.write.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.writeLabels" . | nindent 8 }} + {{- with merge (dict) .Values.loki.podLabels .Values.write.podLabels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + app.kubernetes.io/part-of: memberlist + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{ include "loki.enableServiceLinks" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.writePriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.write.terminationGracePeriodSeconds }} + {{- if .Values.write.initContainers }} + initContainers: + {{- with .Values.write.initContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + containers: + - name: loki + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target={{ .Values.write.targetModule }} + {{- with (concat .Values.global.extraArgs .Values.write.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.loki.server.http_listen_port }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.loki.server.grpc_listen_port }} + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.write.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.write.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + {{- if .Values.write.lifecycle }} + lifecycle: + {{- toYaml .Values.write.lifecycle | nindent 12 }} + {{- else if .Values.write.autoscaling.enabled }} + lifecycle: + preStop: + httpGet: + path: "/ingester/shutdown?terminate=false" + port: http-metrics + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.write.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.write.resources | nindent 12 }} + {{- with .Values.write.extraContainers }} + {{- toYaml . | nindent 8}} + {{- end }} + {{- with .Values.write.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.write.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.write.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.write.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.write.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + {{- if not .Values.write.persistence.volumeClaimsEnabled }} + - name: data + {{- toYaml .Values.write.persistence.dataVolumeParameters | nindent 10 }} + {{- end}} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.write.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.write.persistence.volumeClaimsEnabled }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + {{- with .Values.write.persistence.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.write.persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .Values.write.persistence.size | quote }} + {{- with .Values.write.persistence.selector }} + selector: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.write.extraVolumeClaimTemplates }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/loki/test/config_test.go b/charts/loki/test/config_test.go new file mode 100644 index 0000000..6926c7b --- /dev/null +++ b/charts/loki/test/config_test.go @@ -0,0 +1,220 @@ +package test + +import ( + "os" + "os/exec" + "testing" + + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v2" +) + +type replicas struct { + Replicas int `yaml:"replicas"` +} +type loki struct { + Storage struct { + Type string `yaml:"type"` + } `yaml:"storage"` +} + +type values struct { + DeploymentMode string `yaml:"deploymentMode"` + Backend replicas `yaml:"backend"` + Compactor replicas `yaml:"compactor"` + Distributor replicas `yaml:"distributor"` + IndexGateway replicas `yaml:"indexGateway"` + Ingester replicas `yaml:"ingester"` + Querier replicas `yaml:"querier"` + QueryFrontend replicas `yaml:"queryFrontend"` + QueryScheduler replicas `yaml:"queryScheduler"` + Read replicas `yaml:"read"` + Ruler replicas `yaml:"ruler"` + SingleBinary replicas `yaml:"singleBinary"` + Write replicas `yaml:"write"` + + Loki loki `yaml:"loki"` +} + +func templateConfig(t *testing.T, vals values) error { + y, err := yaml.Marshal(&vals) + require.NoError(t, err) + require.Greater(t, len(y), 0) + + f, err := os.CreateTemp("", "values.yaml") + require.NoError(t, err) + + _, err = f.Write(y) + require.NoError(t, err) + + cmd := exec.Command("helm", "dependency", "build") + // Dependency build needs to be run from the parent directory where the chart is located. + cmd.Dir = "../" + var cmdOutput []byte + if cmdOutput, err = cmd.CombinedOutput(); err != nil { + t.Log("dependency build failed", "err", string(cmdOutput)) + return err + } + + cmd = exec.Command("helm", "template", "../", "--values", f.Name()) + if cmdOutput, err := cmd.CombinedOutput(); err != nil { + t.Log("template failed", "err", string(cmdOutput)) + return err + } + + return nil +} + +// E.Welch these tests fail because the templateConfig function above can't resolve the chart dependencies and I'm not sure how to fix this.... + +//func Test_InvalidConfigs(t *testing.T) { +// t.Run("running both single binary and scalable targets", func(t *testing.T) { +// vals := values{ +// SingleBinary: replicas{Replicas: 1}, +// Write: replicas{Replicas: 1}, +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "gcs"}, +// }, +// } +// require.Error(t, templateConfig(t, vals)) +// }) +// +// t.Run("running both single binary and distributed targets", func(t *testing.T) { +// vals := values{ +// SingleBinary: replicas{Replicas: 1}, +// Distributor: replicas{Replicas: 1}, +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "gcs"}, +// }, +// } +// require.Error(t, templateConfig(t, vals)) +// }) +// +// t.Run("running both scalable and distributed targets", func(t *testing.T) { +// vals := values{ +// Read: replicas{Replicas: 1}, +// Distributor: replicas{Replicas: 1}, +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "gcs"}, +// }, +// } +// require.Error(t, templateConfig(t, vals)) +// }) +// +// t.Run("running scalable with filesystem storage", func(t *testing.T) { +// vals := values{ +// Read: replicas{Replicas: 1}, +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "filesystem"}, +// }, +// } +// +// require.Error(t, templateConfig(t, vals)) +// }) +// +// t.Run("running distributed with filesystem storage", func(t *testing.T) { +// vals := values{ +// Distributor: replicas{Replicas: 1}, +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "filesystem"}, +// }, +// } +// +// require.Error(t, templateConfig(t, vals)) +// }) +//} +// +//func Test_ValidConfigs(t *testing.T) { +// t.Run("single binary", func(t *testing.T) { +// vals := values{ +// +// DeploymentMode: "SingleBinary", +// +// SingleBinary: replicas{Replicas: 1}, +// +// Backend: replicas{Replicas: 0}, +// Compactor: replicas{Replicas: 0}, +// Distributor: replicas{Replicas: 0}, +// IndexGateway: replicas{Replicas: 0}, +// Ingester: replicas{Replicas: 0}, +// Querier: replicas{Replicas: 0}, +// QueryFrontend: replicas{Replicas: 0}, +// QueryScheduler: replicas{Replicas: 0}, +// Read: replicas{Replicas: 0}, +// Ruler: replicas{Replicas: 0}, +// Write: replicas{Replicas: 0}, +// +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "filesystem"}, +// }, +// } +// require.NoError(t, templateConfig(t, vals)) +// }) +// +// t.Run("scalable", func(t *testing.T) { +// vals := values{ +// +// DeploymentMode: "SimpleScalable", +// +// Backend: replicas{Replicas: 1}, +// Read: replicas{Replicas: 1}, +// Write: replicas{Replicas: 1}, +// +// Compactor: replicas{Replicas: 0}, +// Distributor: replicas{Replicas: 0}, +// IndexGateway: replicas{Replicas: 0}, +// Ingester: replicas{Replicas: 0}, +// Querier: replicas{Replicas: 0}, +// QueryFrontend: replicas{Replicas: 0}, +// QueryScheduler: replicas{Replicas: 0}, +// Ruler: replicas{Replicas: 0}, +// SingleBinary: replicas{Replicas: 0}, +// +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "gcs"}, +// }, +// } +// require.NoError(t, templateConfig(t, vals)) +// }) +// +// t.Run("distributed", func(t *testing.T) { +// vals := values{ +// DeploymentMode: "Distributed", +// +// Compactor: replicas{Replicas: 1}, +// Distributor: replicas{Replicas: 1}, +// IndexGateway: replicas{Replicas: 1}, +// Ingester: replicas{Replicas: 1}, +// Querier: replicas{Replicas: 1}, +// QueryFrontend: replicas{Replicas: 1}, +// QueryScheduler: replicas{Replicas: 1}, +// Ruler: replicas{Replicas: 1}, +// +// Backend: replicas{Replicas: 0}, +// Read: replicas{Replicas: 0}, +// SingleBinary: replicas{Replicas: 0}, +// Write: replicas{Replicas: 0}, +// +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "gcs"}, +// }, +// } +// require.NoError(t, templateConfig(t, vals)) +// }) +//} diff --git a/charts/loki/values.yaml b/charts/loki/values.yaml new file mode 100644 index 0000000..32181d7 --- /dev/null +++ b/charts/loki/values.yaml @@ -0,0 +1,3793 @@ +# -- Overrides the version used to determine compatibility of resources with the target Kubernetes cluster. +# This is useful when using `helm template`, because then helm will use the client version of kubectl as the Kubernetes version, +# which may or may not match your cluster's server version. Example: 'v1.24.4'. Set to null to use the version that helm +# devises. +kubeVersionOverride: null + +global: + image: + # -- Overrides the Docker registry globally for all images + registry: null + # -- Overrides the priorityClassName for all pods + priorityClassName: null + # -- configures cluster domain ("cluster.local" by default) + clusterDomain: "cluster.local" + # -- configures DNS service name + dnsService: "kube-dns" + # -- configures DNS service namespace + dnsNamespace: "kube-system" + # -- Common additional CLI arguments for all jobs (that is, -log.level debug, -config.expand-env=true or -log-config-reverse-order) + # scope: admin-api, backend, bloom-builder, bloom-gateway, bloom-planner, compactor, distributor, index-gateway, ingester, overrides-exporter, pattern-ingester, querier, query-frontend, query-scheduler, read, ruler, write. + extraArgs: [] + # -- Common environment variables to add to all pods directly managed by this chart. + # scope: admin-api, backend, bloom-builder, bloom-gateway, bloom-planner, compactor, distributor, index-gateway, ingester, overrides-exporter, pattern-ingester, querier, query-frontend, query-scheduler, read, ruler, write. + extraEnv: [] + # -- Common source of environment injections to add to all pods directly managed by this chart. + # scope: admin-api, backend, bloom-builder, bloom-gateway, bloom-planner, compactor, distributor, index-gateway, ingester, overrides-exporter, pattern-ingester, querier, query-frontend, query-scheduler, read, ruler, write. + # For example to inject values from a Secret, use: + # extraEnvFrom: + # - secretRef: + # name: mysecret + extraEnvFrom: [] + # -- Common volumes to add to all pods directly managed by this chart. + # scope: admin-api, backend, bloom-builder, bloom-gateway, bloom-planner, compactor, distributor, index-gateway, ingester, overrides-exporter, pattern-ingester, querier, query-frontend, query-scheduler, read, ruler, write. + extraVolumes: [] + # -- Common mount points to add to all pods directly managed by this chart. + # scope: admin-api, backend, bloom-builder, bloom-gateway, bloom-planner, compactor, distributor, index-gateway, ingester, overrides-exporter, pattern-ingester, querier, query-frontend, query-scheduler, read, ruler, write. + extraVolumeMounts: [] +# -- Overrides the chart's name +nameOverride: null +# -- Overrides the chart's computed fullname +fullnameOverride: null +# -- Overrides the chart's cluster label +clusterLabelOverride: null +# -- Image pull secrets for Docker images +imagePullSecrets: [] +# -- Deployment mode lets you specify how to deploy Loki. +# There are 3 options: +# - SingleBinary: Loki is deployed as a single binary, useful for small installs typically without HA, up to a few tens of GB/day. +# - SimpleScalable: Loki is deployed as 3 targets: read, write, and backend. Useful for medium installs easier to manage than distributed, up to a about 1TB/day. +# - Distributed: Loki is deployed as individual microservices. The most complicated but most capable, useful for large installs, typically over 1TB/day. +# There are also 2 additional modes used for migrating between deployment modes: +# - SingleBinary<->SimpleScalable: Migrate from SingleBinary to SimpleScalable (or vice versa) +# - SimpleScalable<->Distributed: Migrate from SimpleScalable to Distributed (or vice versa) +# Note: SimpleScalable and Distributed REQUIRE the use of object storage. +deploymentMode: SimpleScalable +###################################################################################################################### +# +# Base Loki Configs including kubernetes configurations and configurations for Loki itself, +# see below for more specifics on Loki's configuration. +# +###################################################################################################################### +# -- Configuration for running Loki +# @default -- See values.yaml +loki: + # Configures the readiness probe for all of the Loki pods + readinessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 30 + timeoutSeconds: 1 + image: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: grafana/loki + # -- Overrides the image tag whose default is the chart's appVersion + tag: 3.4.2 + # -- Overrides the image tag with an image digest + digest: null + # -- Docker image pull policy + pullPolicy: IfNotPresent + # -- Common annotations for all deployments/StatefulSets + annotations: {} + # -- Common annotations for all pods + podAnnotations: {} + # -- Common labels for all pods + podLabels: {} + # -- Common annotations for all services + serviceAnnotations: {} + # -- Common labels for all services + serviceLabels: {} + # -- The number of old ReplicaSets to retain to allow rollback + revisionHistoryLimit: 10 + # -- The SecurityContext for Loki pods + podSecurityContext: + fsGroup: 10001 + runAsGroup: 10001 + runAsNonRoot: true + runAsUser: 10001 + # -- The SecurityContext for Loki containers + containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + # -- Should enableServiceLinks be enabled. Default to enable + enableServiceLinks: true + ###################################################################################################################### + # + # Loki Configuration + # + # There are several ways to pass configuration to Loki, listing them here in order of our preference for how + # you should use this chart. + # 1. Use the templated value of loki.config below and the corresponding override sections which follow. + # This allows us to set a lot of important Loki configurations and defaults and also allows us to maintain them + # over time as Loki changes and evolves. + # 2. Use the loki.structuredConfig section. + # This will completely override the templated value of loki.config, so you MUST provide the entire Loki config + # including any configuration that we set in loki.config unless you explicitly are trying to change one of those + # values and are not able to do so with the templated sections. + # If you choose this approach the burden is on you to maintain any changes we make to the templated config. + # 3. Use an existing secret or configmap to provide the configuration. + # This option is mostly provided for folks who have external processes which provide or modify the configuration. + # When using this option you can specify a different name for loki.generatedConfigObjectName and configObjectName + # if you have a process which takes the generated config and modifies it, or you can stop the chart from generating + # a config entirely by setting loki.generatedConfigObjectName to + # + ###################################################################################################################### + + # -- Defines what kind of object stores the configuration, a ConfigMap or a Secret. + # In order to move sensitive information (such as credentials) from the ConfigMap/Secret to a more secure location (e.g. vault), it is possible to use [environment variables in the configuration](https://grafana.com/docs/loki/latest/configuration/#use-environment-variables-in-the-configuration). + # Such environment variables can be then stored in a separate Secret and injected via the global.extraEnvFrom value. For details about environment injection from a Secret please see [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/#use-case-as-container-environment-variables). + configStorageType: ConfigMap + # -- The name of the object which Loki will mount as a volume containing the config. + # If the configStorageType is Secret, this will be the name of the Secret, if it is ConfigMap, this will be the name of the ConfigMap. + # The value will be passed through tpl. + configObjectName: '{{ include "loki.name" . }}' + # -- The name of the Secret or ConfigMap that will be created by this chart. + # If empty, no configmap or secret will be created. + # The value will be passed through tpl. + generatedConfigObjectName: '{{ include "loki.name" . }}' + # -- Config file contents for Loki + # @default -- See values.yaml + config: | + {{- if .Values.enterprise.enabled}} + {{- tpl .Values.enterprise.config . }} + {{- else }} + auth_enabled: {{ .Values.loki.auth_enabled }} + {{- end }} + + {{- with .Values.loki.server }} + server: + {{- toYaml . | nindent 2}} + {{- end}} + + pattern_ingester: + enabled: {{ .Values.loki.pattern_ingester.enabled }} + + memberlist: + {{- if .Values.loki.memberlistConfig }} + {{- toYaml .Values.loki.memberlistConfig | nindent 2 }} + {{- else }} + {{- if .Values.loki.extraMemberlistConfig}} + {{- toYaml .Values.loki.extraMemberlistConfig | nindent 2}} + {{- end }} + join_members: + - {{ include "loki.memberlist" . }} + {{- with .Values.migrate.fromDistributed }} + {{- if .enabled }} + - {{ .memberlistService }} + {{- end }} + {{- end }} + {{- end }} + + {{- with .Values.loki.ingester }} + ingester: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- if .Values.loki.commonConfig}} + common: + {{- toYaml .Values.loki.commonConfig | nindent 2}} + storage: + {{- include "loki.commonStorageConfig" . | nindent 4}} + {{- end}} + + {{- with .Values.loki.limits_config }} + limits_config: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + runtime_config: + file: /etc/loki/runtime-config/runtime-config.yaml + + {{- with .Values.chunksCache }} + {{- if .enabled }} + chunk_store_config: + chunk_cache_config: + default_validity: {{ .defaultValidity }} + background: + writeback_goroutines: {{ .writebackParallelism }} + writeback_buffer: {{ .writebackBuffer }} + writeback_size_limit: {{ .writebackSizeLimit }} + memcached: + batch_size: {{ .batchSize }} + parallelism: {{ .parallelism }} + memcached_client: + addresses: dnssrvnoa+_memcached-client._tcp.{{ template "loki.fullname" $ }}-chunks-cache.{{ $.Release.Namespace }}.svc + consistent_hash: true + timeout: {{ .timeout }} + max_idle_conns: 72 + {{- end }} + {{- end }} + + {{- if .Values.loki.schemaConfig }} + schema_config: + {{- toYaml .Values.loki.schemaConfig | nindent 2}} + {{- end }} + + {{- if .Values.loki.useTestSchema }} + schema_config: + {{- toYaml .Values.loki.testSchemaConfig | nindent 2}} + {{- end }} + + {{- if .Values.ruler.enabled }} + {{ include "loki.rulerConfig" . }} + {{- end }} + + {{- if and .Values.loki.storage.use_thanos_objstore .Values.ruler.enabled}} + ruler_storage: + {{- include "loki.rulerThanosStorageConfig" . | nindent 2 }} + {{- end }} + + {{- if or .Values.tableManager.retention_deletes_enabled .Values.tableManager.retention_period }} + table_manager: + retention_deletes_enabled: {{ .Values.tableManager.retention_deletes_enabled }} + retention_period: {{ .Values.tableManager.retention_period }} + {{- end }} + + query_range: + align_queries_with_step: true + {{- with .Values.loki.query_range }} + {{- tpl (. | toYaml) $ | nindent 2 }} + {{- end }} + {{- if .Values.resultsCache.enabled }} + {{- with .Values.resultsCache }} + cache_results: true + results_cache: + cache: + default_validity: {{ .defaultValidity }} + background: + writeback_goroutines: {{ .writebackParallelism }} + writeback_buffer: {{ .writebackBuffer }} + writeback_size_limit: {{ .writebackSizeLimit }} + memcached_client: + consistent_hash: true + addresses: dnssrvnoa+_memcached-client._tcp.{{ template "loki.fullname" $ }}-results-cache.{{ $.Release.Namespace }}.svc + timeout: {{ .timeout }} + update_interval: 1m + {{- end }} + {{- end }} + + {{- with .Values.loki.storage_config }} + storage_config: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.query_scheduler }} + query_scheduler: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.compactor }} + compactor: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.analytics }} + analytics: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- if .Values.loki.ui.enabled }} + ui: + discovery: + join_peers: + - '{{ include "loki.queryFrontendFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}' + {{- end }} + {{- with .Values.loki.querier }} + querier: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.index_gateway }} + index_gateway: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.frontend }} + frontend: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.frontend_worker }} + frontend_worker: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.distributor }} + distributor: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + tracing: + enabled: {{ .Values.loki.tracing.enabled }} + + {{- with .Values.loki.bloom_build }} + bloom_build: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.bloom_gateway }} + bloom_gateway: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + # Should authentication be enabled + auth_enabled: true + # -- memberlist configuration (overrides embedded default) + memberlistConfig: {} + # -- Extra memberlist configuration + extraMemberlistConfig: {} + # -- Tenants list to be created on nginx htpasswd file, with name and password keys + tenants: [] + # -- Check https://grafana.com/docs/loki/latest/configuration/#server for more info on the server configuration. + server: + http_listen_port: 3100 + grpc_listen_port: 9095 + http_server_read_timeout: 600s + http_server_write_timeout: 600s + # -- Limits config + limits_config: + reject_old_samples: true + reject_old_samples_max_age: 168h + max_cache_freshness_per_query: 10m + split_queries_by_interval: 15m + query_timeout: 300s + volume_enabled: true + # -- Provides a reloadable runtime configuration file for some specific configuration + runtimeConfig: {} + # -- Check https://grafana.com/docs/loki/latest/configuration/#common_config for more info on how to provide a common configuration + commonConfig: + path_prefix: /var/loki + replication_factor: 3 + compactor_address: '{{ include "loki.compactorAddress" . }}' + # -- Storage config. Providing this will automatically populate all necessary storage configs in the templated config. + # -- In case of using thanos storage, enable use_thanos_objstore and the configuration should be done inside the object_store section. + storage: + # Loki requires a bucket for chunks and the ruler. GEL requires a third bucket for the admin API. + # Please provide these values if you are using object storage. + # bucketNames: + # chunks: FIXME + # ruler: FIXME + # admin: FIXME + type: s3 + s3: + s3: null + endpoint: null + region: null + secretAccessKey: null + accessKeyId: null + signatureVersion: null + s3ForcePathStyle: false + insecure: false + http_config: {} + # -- Check https://grafana.com/docs/loki/latest/configure/#s3_storage_config for more info on how to provide a backoff_config + backoff_config: {} + disable_dualstack: false + gcs: + chunkBufferSize: 0 + requestTimeout: "0s" + enableHttp2: true + azure: + accountName: null + accountKey: null + connectionString: null + useManagedIdentity: false + useFederatedToken: false + userAssignedId: null + requestTimeout: null + endpointSuffix: null + chunkDelimiter: null + swift: + auth_version: null + auth_url: null + internal: null + username: null + user_domain_name: null + user_domain_id: null + user_id: null + password: null + domain_id: null + domain_name: null + project_id: null + project_name: null + project_domain_id: null + project_domain_name: null + region_name: null + container_name: null + max_retries: null + connect_timeout: null + request_timeout: null + filesystem: + chunks_directory: /var/loki/chunks + rules_directory: /var/loki/rules + admin_api_directory: /var/loki/admin + + # Loki now supports using thanos storage clients for connecting to object storage backend. + # This will become the default way to configure storage in a future releases. + use_thanos_objstore: false + + object_store: + # Type of object store. Valid options are: s3, gcs, azure + type: s3 + # Optional prefix for storage keys + storage_prefix: null + # S3 configuration (when type is "s3") + s3: + # S3 endpoint URL + endpoint: null + # Optional region + region: null + # Optional access key + access_key_id: null + # Optional secret key + secret_access_key: null + # Optional. Enable if using self-signed TLS + insecure: false + # Optional server-side encryption configuration + sse: {} + # Optional HTTP client configuration + http: {} + + # GCS configuration (when type is "gcs") + gcs: + # Name of the bucket + bucket_name: null + # Optional service account JSON + service_account: null + + # Azure configuration (when type is "azure") + azure: + # Storage account name + account_name: null + # Optional storage account key + account_key: null + + # -- Configure memcached as an external cache for chunk and results cache. Disabled by default + # must enable and specify a host for each cache you would like to use. + memcached: + chunk_cache: + enabled: false + host: "" + service: "memcached-client" + batch_size: 256 + parallelism: 10 + results_cache: + enabled: false + host: "" + service: "memcached-client" + timeout: "500ms" + default_validity: "12h" + # -- Check https://grafana.com/docs/loki/latest/configuration/#schema_config for more info on how to configure schemas + schemaConfig: {} + # -- a real Loki install requires a proper schemaConfig defined above this, however for testing or playing around + # you can enable useTestSchema + useTestSchema: false + testSchemaConfig: + configs: + - from: 2024-04-01 + store: tsdb + object_store: '{{ include "loki.testSchemaObjectStore" . }}' + schema: v13 + index: + prefix: index_ + period: 24h + # -- Check https://grafana.com/docs/loki/latest/configuration/#ruler for more info on configuring ruler + rulerConfig: + wal: + dir: /var/loki/ruler-wal + # -- Structured loki configuration, takes precedence over `loki.config`, `loki.schemaConfig`, `loki.storageConfig` + structuredConfig: {} + # -- Additional query scheduler config + query_scheduler: {} + # -- Additional storage config + storage_config: + boltdb_shipper: + index_gateway_client: + server_address: '{{ include "loki.indexGatewayAddress" . }}' + tsdb_shipper: + index_gateway_client: + server_address: '{{ include "loki.indexGatewayAddress" . }}' + bloom_shipper: + working_directory: /var/loki/data/bloomshipper + hedging: + at: "250ms" + max_per_second: 20 + up_to: 3 + # -- Optional compactor configuration + compactor: {} + # -- Optional pattern ingester configuration + pattern_ingester: + enabled: false + # -- Optional analytics configuration + analytics: {} + # -- Optional Loki UI: Provides access to a operators UI for Loki distributed. When enabled UI will be available at /ui/ of loki-gateway + ui: + # Disabled by default for backwards compatibility. Enable to use the Loki UI. + enabled: false + gateway: + # enable gateway proxying to UI under /ui + enabled: true + # -- Optional querier configuration + query_range: {} + # -- Optional querier configuration + querier: {} + # -- Optional ingester configuration + ingester: {} + # -- Optional index gateway configuration + index_gateway: + mode: simple + frontend: + scheduler_address: '{{ include "loki.querySchedulerAddress" . }}' + tail_proxy_url: '{{ include "loki.querierAddress" . }}' + frontend_worker: + scheduler_address: '{{ include "loki.querySchedulerAddress" . }}' + # -- Optional distributor configuration + distributor: {} + # -- Enable tracing + tracing: + enabled: false + bloom_build: + enabled: false + builder: + planner_address: '{{ include "loki.bloomPlannerAddress" . }}' + bloom_gateway: + enabled: false + client: + addresses: '{{ include "loki.bloomGatewayAddresses" . }}' +###################################################################################################################### +# +# Enterprise Loki Configs +# +###################################################################################################################### + +# -- Configuration for running Enterprise Loki +enterprise: + # Enable enterprise features, license must be provided + enabled: false + # Default verion of GEL to deploy + version: 3.4.0 + # -- Optional name of the GEL cluster, otherwise will use .Release.Name + # The cluster name must match what is in your GEL license + cluster_name: null + # -- Grafana Enterprise Logs license + # In order to use Grafana Enterprise Logs features, you will need to provide + # the contents of your Grafana Enterprise Logs license, either by providing the + # contents of the license.jwt, or the name Kubernetes Secret that contains your + # license.jwt. + # To set the license contents, use the flag `--set-file 'enterprise.license.contents=./license.jwt'` + license: + contents: "NOTAVALIDLICENSE" + # -- Set to true when providing an external license + useExternalLicense: false + # -- Name of external license secret to use + externalLicenseName: null + # -- Name of the external config secret to use + externalConfigName: "" + # -- Use GEL gateway, if false will use the default nginx gateway + gelGateway: true + # -- If enabled, the correct admin_client storage will be configured. If disabled while running enterprise, + # make sure auth is set to `type: trust`, or that `auth_enabled` is set to `false`. + adminApi: + enabled: true + # enterprise specific sections of the config.yaml file + config: | + {{- if .Values.enterprise.adminApi.enabled }} + admin_client: + {{ include "enterprise-logs.adminAPIStorageConfig" . | nindent 2 }} + {{ end }} + auth: + type: {{ .Values.enterprise.adminApi.enabled | ternary "enterprise" "trust" }} + auth_enabled: {{ .Values.loki.auth_enabled }} + cluster_name: {{ include "loki.clusterName" . }} + license: + path: /etc/loki/license/license.jwt + image: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: grafana/enterprise-logs + # -- Docker image tag + tag: 3.4.1 + # -- Overrides the image tag with an image digest + digest: null + # -- Docker image pull policy + pullPolicy: IfNotPresent + adminToken: + # -- Alternative name for admin token secret, needed by tokengen and provisioner jobs + secret: null + # -- Additional namespace to also create the token in. Useful if your Grafana instance + # is in a different namespace + additionalNamespaces: [] + # -- Alternative name of the secret to store token for the canary + canarySecret: null + # -- Configuration for `tokengen` target + tokengen: + # -- Whether the job should be part of the deployment + enabled: true + # -- Comma-separated list of Loki modules to load for tokengen + targetModule: "tokengen" + # -- Additional CLI arguments for the `tokengen` target + extraArgs: [] + # -- Additional Kubernetes environment + env: [] + # -- Additional labels for the `tokengen` Job + labels: {} + # -- Additional annotations for the `tokengen` Job + annotations: {} + # -- Affinity for tokengen Pods + affinity: {} + # -- Node selector for tokengen Pods + nodeSelector: {} + # -- Tolerations for tokengen Job + tolerations: [] + # -- Additional volumes for Pods + extraVolumes: [] + # -- Additional volume mounts for Pods + extraVolumeMounts: [] + # -- Run containers as user `enterprise-logs(uid=10001)` + securityContext: + runAsNonRoot: true + runAsGroup: 10001 + runAsUser: 10001 + fsGroup: 10001 + # -- Environment variables from secrets or configmaps to add to the tokengen pods + extraEnvFrom: [] + # -- The name of the PriorityClass for tokengen Pods + priorityClassName: "" + # -- Configuration for `provisioner` target + provisioner: + # -- Whether the job should be part of the deployment + enabled: true + # -- Name of the secret to store provisioned tokens in + provisionedSecretPrefix: null + # -- Hook type(s) to customize when the job runs. defaults to post-install + hookType: "post-install" + # -- Additional tenants to be created. Each tenant will get a read and write policy + # and associated token. Tenant must have a name and a namespace for the secret containting + # the token to be created in. For example + # additionalTenants: + # - name: loki + # secretNamespace: grafana + additionalTenants: [] + # -- Additional Kubernetes environment + env: [] + # -- Additional labels for the `provisioner` Job + labels: {} + # -- Additional annotations for the `provisioner` Job + annotations: {} + # -- Affinity for tokengen Pods + affinity: {} + # -- Node selector for tokengen Pods + nodeSelector: {} + # -- Tolerations for tokengen Pods + tolerations: [] + # -- The name of the PriorityClass for provisioner Job + priorityClassName: null + # -- Run containers as user `enterprise-logs(uid=10001)` + securityContext: + runAsNonRoot: true + runAsGroup: 10001 + runAsUser: 10001 + fsGroup: 10001 + # -- Provisioner image to Utilize + image: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: grafana/enterprise-logs-provisioner + # -- Overrides the image tag whose default is the chart's appVersion + tag: null + # -- Overrides the image tag with an image digest + digest: null + # -- Docker image pull policy + pullPolicy: IfNotPresent + # -- Volume mounts to add to the provisioner pods + extraVolumeMounts: [] +# -- kubetclImage is used in the enterprise provisioner and tokengen jobs +kubectlImage: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: bitnami/kubectl + # -- Overrides the image tag whose default is the chart's appVersion + tag: null + # -- Overrides the image tag with an image digest + digest: null + # -- Docker image pull policy + pullPolicy: IfNotPresent +###################################################################################################################### +# +# Chart Testing +# +###################################################################################################################### + +# -- Section for configuring optional Helm test +test: + enabled: true + # -- Used to directly query the metrics endpoint of the canary for testing, this approach avoids needing prometheus for testing. + # This in a newer approach to using prometheusAddress such that tests do not have a dependency on prometheus + canaryServiceAddress: "http://loki-canary:3500/metrics" + # -- Address of the prometheus server to query for the test. This overrides any value set for canaryServiceAddress. + # This is kept for backward compatibility and may be removed in future releases. Previous value was 'http://prometheus:9090' + prometheusAddress: "" + # -- Number of times to retry the test before failing + timeout: 1m + # -- Additional labels for the test pods + labels: {} + # -- Additional annotations for test pods + annotations: {} + # -- Image to use for loki canary + image: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: grafana/loki-helm-test + # -- Overrides the image tag whose default is the chart's appVersion + tag: "ewelch-distributed-helm-chart-17db5ee" + # -- Overrides the image tag with an image digest + digest: null + # -- Docker image pull policy + pullPolicy: IfNotPresent +# The Loki canary pushes logs to and queries from this loki installation to test +# that it's working correctly +lokiCanary: + enabled: true + # -- If true, the canary will send directly to Loki via the address configured for verification -- + # -- If false, it will write to stdout and an Agent will be needed to scrape and send the logs -- + push: true + # -- The name of the label to look for at loki when doing the checks. + labelname: pod + # -- Additional annotations for the `loki-canary` Daemonset + annotations: {} + # -- Additional labels for each `loki-canary` pod + podLabels: {} + service: + # -- Annotations for loki-canary Service + annotations: {} + # -- Additional labels for loki-canary Service + labels: {} + # -- Additional CLI arguments for the `loki-canary' command + extraArgs: [] + # -- Environment variables to add to the canary pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the canary pods + extraEnvFrom: [] + # -- Volume mounts to add to the canary pods + extraVolumeMounts: [] + # -- Volumes to add to the canary pods + extraVolumes: [] + # -- Resource requests and limits for the canary + resources: {} + # -- DNS config for canary pods + dnsConfig: {} + # -- Node selector for canary pods + nodeSelector: {} + # -- Tolerations for canary pods + tolerations: [] + # -- The name of the PriorityClass for loki-canary pods + priorityClassName: null + # -- Image to use for loki canary + image: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: grafana/loki-canary + # -- Overrides the image tag whose default is the chart's appVersion + tag: null + # -- Overrides the image tag with an image digest + digest: null + # -- Docker image pull policy + pullPolicy: IfNotPresent + # -- Update strategy for the `loki-canary` Daemonset pods + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 +###################################################################################################################### +# +# Service Accounts and Kubernetes RBAC +# +###################################################################################################################### +serviceAccount: + # -- Specifies whether a ServiceAccount should be created + create: true + # -- The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: null + # -- Image pull secrets for the service account + imagePullSecrets: [] + # -- Annotations for the service account + annotations: {} + # -- Labels for the service account + labels: {} + # -- Set this toggle to false to opt out of automounting API credentials for the service account + automountServiceAccountToken: true +# RBAC configuration +rbac: + # -- If pspEnabled true, a PodSecurityPolicy is created for K8s that use psp. + pspEnabled: false + # -- For OpenShift set pspEnabled to 'false' and sccEnabled to 'true' to use the SecurityContextConstraints. + sccEnabled: false + # -- Specify PSP annotations + # Ref: https://kubernetes.io/docs/reference/access-authn-authz/psp-to-pod-security-standards/#podsecuritypolicy-annotations + pspAnnotations: {} + # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' + # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + # -- Whether to install RBAC in the namespace only or cluster-wide. Useful if you want to watch ConfigMap globally. + namespaced: false +###################################################################################################################### +# +# Network Policy configuration +# +###################################################################################################################### +networkPolicy: + # -- Specifies whether Network Policies should be created + enabled: false + # -- Specifies whether the policies created will be standard Network Policies (flavor: kubernetes) + # or Cilium Network Policies (flavor: cilium) + flavor: kubernetes + metrics: + # -- Specifies the Pods which are allowed to access the metrics port. + # As this is cross-namespace communication, you also need the namespaceSelector. + podSelector: {} + # -- Specifies the namespaces which are allowed to access the metrics port + namespaceSelector: {} + # -- Specifies specific network CIDRs which are allowed to access the metrics port. + # In case you use namespaceSelector, you also have to specify your kubelet networks here. + # The metrics ports are also used for probes. + cidrs: [] + ingress: + # -- Specifies the Pods which are allowed to access the http port. + # As this is cross-namespace communication, you also need the namespaceSelector. + podSelector: {} + # -- Specifies the namespaces which are allowed to access the http port + namespaceSelector: {} + alertmanager: + # -- Specify the alertmanager port used for alerting + port: 9093 + # -- Specifies the alertmanager Pods. + # As this is cross-namespace communication, you also need the namespaceSelector. + podSelector: {} + # -- Specifies the namespace the alertmanager is running in + namespaceSelector: {} + externalStorage: + # -- Specify the port used for external storage, e.g. AWS S3 + ports: [] + # -- Specifies specific network CIDRs you want to limit access to + cidrs: [] + discovery: + # -- (int) Specify the port used for discovery + port: null + # -- Specifies the Pods labels used for discovery. + # As this is cross-namespace communication, you also need the namespaceSelector. + podSelector: {} + # -- Specifies the namespace the discovery Pods are running in + namespaceSelector: {} + egressWorld: + # -- Enable additional cilium egress rules to external world for write, read and backend. + enabled: false + egressKubeApiserver: + # -- Enable additional cilium egress rules to kube-apiserver for backend. + enabled: false +###################################################################################################################### +# +# Global memberlist configuration +# +###################################################################################################################### + +# Configuration for the memberlist service +memberlist: + service: + publishNotReadyAddresses: false + annotations: {} +###################################################################################################################### +# +# adminAPI configuration, enterprise only. +# +###################################################################################################################### + +# -- Configuration for the `admin-api` target +adminApi: + # -- Define the amount of instances + replicas: 1 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + # -- Additional CLI arguments for the `admin-api` target + extraArgs: {} + # -- Environment variables from secrets or configmaps to add to the admin-api pods + extraEnvFrom: [] + # -- Additional labels for the `admin-api` Deployment + labels: {} + # -- Additional annotations for the `admin-api` Deployment + annotations: {} + # -- Additional labels and annotations for the `admin-api` Service + service: + labels: {} + annotations: {} + # -- Run container as user `enterprise-logs(uid=10001)` + # `fsGroup` must not be specified, because these security options are applied + # on container level not on Pod level. + podSecurityContext: + runAsNonRoot: true + runAsGroup: 10001 + runAsUser: 10001 + containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + # -- Update strategy + strategy: + type: RollingUpdate + # -- Readiness probe + readinessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 45 + # -- Request and limit Kubernetes resources + # -- Values are defined in small.yaml and large.yaml + resources: {} + # -- Configure optional environment variables + env: [] + # -- Configure optional initContainers + initContainers: [] + # -- Conifgure optional extraContainers + extraContainers: [] + # -- Additional volumes for Pods + extraVolumes: [] + # -- Additional volume mounts for Pods + extraVolumeMounts: [] + # -- Affinity for admin-api Pods + affinity: {} + # -- Node selector for admin-api Pods + nodeSelector: {} + # -- Topology Spread Constraints for admin-api pods + topologySpreadConstraints: [] + # -- Tolerations for admin-api Pods + tolerations: [] + # -- Grace period to allow the admin-api to shutdown before it is killed + terminationGracePeriodSeconds: 60 +###################################################################################################################### +# +# Gateway and Ingress +# +# By default this chart will deploy a Nginx container to act as a gateway which handles routing of traffic +# and can also do auth. +# +# If you would prefer you can optionally disable this and enable using k8s ingress to do the incoming routing. +# +###################################################################################################################### + +# Configuration for the gateway +gateway: + # -- Specifies whether the gateway should be enabled + enabled: true + # -- Number of replicas for the gateway + replicas: 1 + # -- Default container port + containerPort: 8080 + # -- Enable logging of 2xx and 3xx HTTP requests + verboseLogging: true + autoscaling: + # -- Enable autoscaling for the gateway + enabled: false + # -- Minimum autoscaling replicas for the gateway + minReplicas: 1 + # -- Maximum autoscaling replicas for the gateway + maxReplicas: 3 + # -- Target CPU utilisation percentage for the gateway + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the gateway + targetMemoryUtilizationPercentage: + # -- See `kubectl explain deployment.spec.strategy` for more + # -- ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy + # -- Behavior policies while scaling. + behavior: {} + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 60 + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + deploymentStrategy: + type: RollingUpdate + image: + # -- The Docker registry for the gateway image + registry: docker.io + # -- The gateway image repository + repository: nginxinc/nginx-unprivileged + # -- The gateway image tag + tag: 1.27-alpine + # -- Overrides the gateway image tag with an image digest + digest: null + # -- The gateway image pull policy + pullPolicy: IfNotPresent + # -- The name of the PriorityClass for gateway pods + priorityClassName: null + # -- Annotations for gateway deployment + annotations: {} + # -- Annotations for gateway pods + podAnnotations: {} + # -- Additional labels for gateway pods + podLabels: {} + # -- Additional CLI args for the gateway + extraArgs: [] + # -- Environment variables to add to the gateway pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the gateway pods + extraEnvFrom: [] + # -- Lifecycle for the gateway container + lifecycle: {} + # -- Volumes to add to the gateway pods + extraVolumes: [] + # -- Volume mounts to add to the gateway pods + extraVolumeMounts: [] + # -- The SecurityContext for gateway containers + podSecurityContext: + fsGroup: 101 + runAsGroup: 101 + runAsNonRoot: true + runAsUser: 101 + # -- The SecurityContext for gateway containers + containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + # -- Resource requests and limits for the gateway + resources: {} + # -- Containers to add to the gateway pods + extraContainers: [] + # -- Grace period to allow the gateway to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for gateway pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: gateway + topologyKey: kubernetes.io/hostname + # -- DNS config for gateway pods + dnsConfig: {} + # -- Node selector for gateway pods + nodeSelector: {} + # -- Topology Spread Constraints for gateway pods + topologySpreadConstraints: [] + # -- Tolerations for gateway pods + tolerations: [] + # Gateway service configuration + service: + # -- Port of the gateway service + port: 80 + # -- Type of the gateway service + type: ClusterIP + # -- ClusterIP of the gateway service + clusterIP: null + # -- (int) Node port if service type is NodePort + nodePort: null + # -- Load balancer IPO address if service type is LoadBalancer + loadBalancerIP: null + # -- Annotations for the gateway service + annotations: {} + # -- Labels for gateway service + labels: {} + # Gateway ingress configuration + ingress: + # -- Specifies whether an ingress for the gateway should be created + enabled: false + # -- Ingress Class Name. MAY be required for Kubernetes versions >= 1.18 + ingressClassName: "" + # -- Annotations for the gateway ingress + annotations: {} + # -- Labels for the gateway ingress + labels: {} + # -- Hosts configuration for the gateway ingress, passed through the `tpl` function to allow templating + hosts: + - host: gateway.loki.example.com + paths: + - path: / + # -- pathType (e.g. ImplementationSpecific, Prefix, .. etc.) might also be required by some Ingress Controllers + # pathType: Prefix + # -- TLS configuration for the gateway ingress. Hosts passed through the `tpl` function to allow templating + tls: + - secretName: loki-gateway-tls + hosts: + - gateway.loki.example.com + # Basic auth configuration + basicAuth: + # -- Enables basic authentication for the gateway + enabled: false + # -- The basic auth username for the gateway + username: null + # -- The basic auth password for the gateway + password: null + # -- Uses the specified users from the `loki.tenants` list to create the htpasswd file. + # if `loki.tenants` is not set, the `gateway.basicAuth.username` and `gateway.basicAuth.password` are used. + # The value is templated using `tpl`. Override this to use a custom htpasswd, e.g. in case the default causes + # high CPU load. + # @default -- Either `loki.tenants` or `gateway.basicAuth.username` and `gateway.basicAuth.password`. + htpasswd: >- + {{ if .Values.loki.tenants }} + + + {{- range $t := .Values.loki.tenants }} + {{ htpasswd (required "All tenants must have a 'name' set" $t.name) (required "All tenants must have a 'password' set" $t.password) }} + + + {{- end }} + {{ else }} {{ htpasswd (required "'gateway.basicAuth.username' is required" .Values.gateway.basicAuth.username) (required "'gateway.basicAuth.password' is required" .Values.gateway.basicAuth.password) }} {{ end }} + # -- Existing basic auth secret to use. Must contain '.htpasswd' + existingSecret: null + # Configures the readiness probe for the gateway + readinessProbe: + httpGet: + path: / + port: http-metrics + initialDelaySeconds: 15 + timeoutSeconds: 1 + nginxConfig: + # -- Which schema to be used when building URLs. Can be 'http' or 'https'. + schema: http + # -- Enable listener for IPv6, disable on IPv4-only systems + enableIPv6: true + # -- NGINX log format + logFormat: |- + main '$remote_addr - $remote_user [$time_local] $status ' + '"$request" $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + # -- Allows appending custom configuration to the server block + serverSnippet: "" + # -- Allows appending custom configuration to the http block, passed through the `tpl` function to allow templating + httpSnippet: >- + {{ if .Values.loki.tenants }}proxy_set_header X-Scope-OrgID $remote_user;{{ end }} + # -- Allows customizing the `client_max_body_size` directive + clientMaxBodySize: 4M + # -- Whether ssl should be appended to the listen directive of the server block or not. + ssl: false + # -- Override Read URL + customReadUrl: null + # -- Override Write URL + customWriteUrl: null + # -- Override Backend URL + customBackendUrl: null + # -- Allows overriding the DNS resolver address nginx will use. + resolver: "" + # -- Config file contents for Nginx. Passed through the `tpl` function to allow templating + # @default -- See values.yaml + file: | + {{- include "loki.nginxFile" . | indent 2 -}} +# -- If running enterprise and using the default enterprise gateway, configs go here. +enterpriseGateway: + # -- Define the amount of instances + replicas: 1 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + # -- Additional CLI arguments for the `gateway` target + extraArgs: {} + # -- Environment variables from secrets or configmaps to add to the enterprise gateway pods + extraEnvFrom: [] + # -- Additional labels for the `gateway` Pod + labels: {} + # -- Additional annotations for the `gateway` Pod + annotations: {} + # -- Additional labels and annotations for the `gateway` Service + # -- Service overriding service type + service: + type: ClusterIP + labels: {} + annotations: {} + # -- Run container as user `enterprise-logs(uid=10001)` + podSecurityContext: + runAsNonRoot: true + runAsGroup: 10001 + runAsUser: 10001 + fsGroup: 10001 + containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + # -- If you want to use your own proxy URLs, set this to false. + useDefaultProxyURLs: true + # -- update strategy + strategy: + type: RollingUpdate + # -- Readiness probe + readinessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 45 + # -- Request and limit Kubernetes resources + # -- Values are defined in small.yaml and large.yaml + resources: {} + # -- Configure optional environment variables + env: [] + # -- Configure optional initContainers + initContainers: [] + # -- Conifgure optional extraContainers + extraContainers: [] + # -- Additional volumes for Pods + extraVolumes: [] + # -- Additional volume mounts for Pods + extraVolumeMounts: [] + # -- Affinity for gateway Pods + affinity: {} + # -- Node selector for gateway Pods + nodeSelector: {} + # -- Topology Spread Constraints for enterprise-gateway pods + topologySpreadConstraints: [] + # -- Tolerations for gateway Pods + tolerations: [] + # -- Grace period to allow the gateway to shutdown before it is killed + terminationGracePeriodSeconds: 60 +# -- Ingress configuration Use either this ingress or the gateway, but not both at once. +# If you enable this, make sure to disable the gateway. +# You'll need to supply authn configuration for your ingress controller. +ingress: + enabled: false + ingressClassName: "" + annotations: {} + # nginx.ingress.kubernetes.io/auth-type: basic + # nginx.ingress.kubernetes.io/auth-secret: loki-distributed-basic-auth + # nginx.ingress.kubernetes.io/auth-secret-type: auth-map + # nginx.ingress.kubernetes.io/configuration-snippet: | + # proxy_set_header X-Scope-OrgID $remote_user; + labels: {} + # blackbox.monitoring.exclude: "true" + paths: + # -- Paths that are exposed by Loki Distributor. + # If deployment mode is Distributed, the requests are forwarded to the service: `{{"loki.distributorFullname"}}`. + # If deployment mode is SimpleScalable, the requests are forwarded to write k8s service: `{{"loki.writeFullname"}}`. + # If deployment mode is SingleBinary, the requests are forwarded to the central/single k8s service: `{{"loki.singleBinaryFullname"}}` + distributor: + - /api/prom/push + - /loki/api/v1/push + - /otlp/v1/logs + # -- Paths that are exposed by Loki Query Frontend. + # If deployment mode is Distributed, the requests are forwarded to the service: `{{"loki.queryFrontendFullname"}}`. + # If deployment mode is SimpleScalable, the requests are forwarded to write k8s service: `{{"loki.readFullname"}}`. + # If deployment mode is SingleBinary, the requests are forwarded to the central/single k8s service: `{{"loki.singleBinaryFullname"}}` + queryFrontend: + - /api/prom/query + # this path covers labels and labelValues endpoints + - /api/prom/label + - /api/prom/series + - /api/prom/tail + - /loki/api/v1/query + - /loki/api/v1/query_range + - /loki/api/v1/tail + # this path covers labels and labelValues endpoints + - /loki/api/v1/label + - /loki/api/v1/labels + - /loki/api/v1/series + - /loki/api/v1/index/stats + - /loki/api/v1/index/volume + - /loki/api/v1/index/volume_range + - /loki/api/v1/format_query + - /loki/api/v1/detected_field + - /loki/api/v1/detected_fields + - /loki/api/v1/detected_labels + - /loki/api/v1/patterns + # -- Paths that are exposed by Loki Ruler. + # If deployment mode is Distributed, the requests are forwarded to the service: `{{"loki.rulerFullname"}}`. + # If deployment mode is SimpleScalable, the requests are forwarded to k8s service: `{{"loki.backendFullname"}}`. + # If deployment mode is SimpleScalable but `read.legacyReadTarget` is `true`, the requests are forwarded to k8s service: `{{"loki.readFullname"}}`. + # If deployment mode is SingleBinary, the requests are forwarded to the central/single k8s service: `{{"loki.singleBinaryFullname"}}` + ruler: + - /api/prom/rules + - /api/prom/api/v1/rules + - /api/prom/api/v1/alerts + - /loki/api/v1/rules + - /prometheus/api/v1/rules + - /prometheus/api/v1/alerts + # -- Hosts configuration for the ingress, passed through the `tpl` function to allow templating + hosts: + - loki.example.com + # -- TLS configuration for the ingress. Hosts passed through the `tpl` function to allow templating + tls: [] +# - hosts: +# - loki.example.com +# secretName: loki-distributed-tls + +###################################################################################################################### +# +# Migration +# +###################################################################################################################### + +# -- Options that may be necessary when performing a migration from another helm chart +migrate: + # -- When migrating from a distributed chart like loki-distributed or enterprise-logs + fromDistributed: + # -- Set to true if migrating from a distributed helm chart + enabled: false + # -- If migrating from a distributed service, provide the distributed deployment's + # memberlist service DNS so the new deployment can join its ring. + memberlistService: "" +###################################################################################################################### +# +# Single Binary Deployment +# +# For small Loki installations up to a few 10's of GB per day, or for testing and development. +# +###################################################################################################################### + +# Configuration for the single binary node(s) +singleBinary: + # -- Number of replicas for the single binary + replicas: 0 + autoscaling: + # -- Enable autoscaling + enabled: false + # -- Minimum autoscaling replicas for the single binary + minReplicas: 1 + # -- Maximum autoscaling replicas for the single binary + maxReplicas: 3 + # -- Target CPU utilisation percentage for the single binary + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the single binary + targetMemoryUtilizationPercentage: + image: + # -- The Docker registry for the single binary image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the single binary image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the single binary image. Overrides `loki.image.tag` + tag: null + # -- The name of the PriorityClass for single binary pods + priorityClassName: null + # -- Annotations for single binary StatefulSet + annotations: {} + # -- Annotations for single binary pods + podAnnotations: {} + # -- Additional labels for each `single binary` pod + podLabels: {} + # -- Additional selector labels for each `single binary` pod + selectorLabels: {} + service: + # -- Annotations for single binary Service + annotations: {} + # -- Additional labels for single binary Service + labels: {} + # -- Comma-separated list of Loki modules to load for the single binary + targetModule: "all" + # -- Labels for single binary service + extraArgs: [] + # -- Environment variables to add to the single binary pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the single binary pods + extraEnvFrom: [] + # -- Extra containers to add to the single binary loki pod + extraContainers: [] + # -- Init containers to add to the single binary pods + initContainers: [] + # -- Volume mounts to add to the single binary pods + extraVolumeMounts: [] + # -- Volumes to add to the single binary pods + extraVolumes: [] + # -- Resource requests and limits for the single binary + resources: {} + # -- Grace period to allow the single binary to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for single binary pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: single-binary + topologyKey: kubernetes.io/hostname + # -- DNS config for single binary pods + dnsConfig: {} + # -- Node selector for single binary pods + nodeSelector: {} + # -- Tolerations for single binary pods + tolerations: [] + persistence: + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: true + # -- Enable persistent disk + enabled: true + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Selector for persistent disk + selector: null + # -- Annotations for volume claim + annotations: {} +###################################################################################################################### +# +# Simple Scalable Deployment (SSD) Mode +# +# For small to medium size Loki deployments up to around 1 TB/day, this is the default mode for this helm chart +# +###################################################################################################################### + +# Configuration for the write pod(s) +write: + # -- Number of replicas for the write + replicas: 3 + autoscaling: + # -- Enable autoscaling for the write. + enabled: false + # -- Minimum autoscaling replicas for the write. + minReplicas: 2 + # -- Maximum autoscaling replicas for the write. + maxReplicas: 6 + # -- Target CPU utilisation percentage for the write. + targetCPUUtilizationPercentage: 60 + # -- Target memory utilization percentage for the write. + targetMemoryUtilizationPercentage: + # -- Behavior policies while scaling. + behavior: + # -- see https://github.com/grafana/loki/blob/main/docs/sources/operations/storage/wal.md#how-to-scale-updown for scaledown details + scaleUp: + policies: + - type: Pods + value: 1 + periodSeconds: 900 + scaleDown: + policies: + - type: Pods + value: 1 + periodSeconds: 1800 + stabilizationWindowSeconds: 3600 + image: + # -- The Docker registry for the write image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the write image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the write image. Overrides `loki.image.tag` + tag: null + # -- The name of the PriorityClass for write pods + priorityClassName: null + # -- Annotations for write StatefulSet + annotations: {} + # -- Annotations for write pods + podAnnotations: {} + # -- Additional labels for each `write` pod + podLabels: {} + # -- Additional selector labels for each `write` pod + selectorLabels: {} + service: + # -- Annotations for write Service + annotations: {} + # -- Additional labels for write Service + labels: {} + # -- Comma-separated list of Loki modules to load for the write + targetModule: "write" + # -- Additional CLI args for the write + extraArgs: [] + # -- Environment variables to add to the write pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the write pods + extraEnvFrom: [] + # -- Lifecycle for the write container + lifecycle: {} + # -- The default /flush_shutdown preStop hook is recommended as part of the ingester + # scaledown process so it's added to the template by default when autoscaling is enabled, + # but it's disabled to optimize rolling restarts in instances that will never be scaled + # down or when using chunks storage with WAL disabled. + # https://github.com/grafana/loki/blob/main/docs/sources/operations/storage/wal.md#how-to-scale-updown + # -- Init containers to add to the write pods + initContainers: [] + # -- Containers to add to the write pods + extraContainers: [] + # -- Volume mounts to add to the write pods + extraVolumeMounts: [] + # -- Volumes to add to the write pods + extraVolumes: [] + # -- volumeClaimTemplates to add to StatefulSet + extraVolumeClaimTemplates: [] + # -- Resource requests and limits for the write + resources: {} + # -- Grace period to allow the write to shutdown before it is killed. Especially for the ingester, + # this must be increased. It must be long enough so writes can be gracefully shutdown flushing/transferring + # all data and to successfully leave the member ring on shutdown. + terminationGracePeriodSeconds: 300 + # -- Affinity for write pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: write + topologyKey: kubernetes.io/hostname + # -- DNS config for write pods + dnsConfig: {} + # -- Node selector for write pods + nodeSelector: {} + # -- Topology Spread Constraints for write pods + topologySpreadConstraints: [] + # -- Tolerations for write pods + tolerations: [] + # -- The default is to deploy all pods in parallel. + podManagementPolicy: "Parallel" + persistence: + # -- Enable volume claims in pod spec + volumeClaimsEnabled: true + # -- Parameters used for the `data` volume when volumeClaimEnabled if false + dataVolumeParameters: + emptyDir: {} + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Selector for persistent disk + selector: null + # -- Annotations for volume claim + annotations: {} +# -- Configuration for the read pod(s) +read: + # -- Number of replicas for the read + replicas: 3 + autoscaling: + # -- Enable autoscaling for the read, this is only used if `queryIndex.enabled: true` + enabled: false + # -- Minimum autoscaling replicas for the read + minReplicas: 2 + # -- Maximum autoscaling replicas for the read + maxReplicas: 6 + # -- Target CPU utilisation percentage for the read + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the read + targetMemoryUtilizationPercentage: + # -- Behavior policies while scaling. + behavior: {} + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 60 + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + image: + # -- The Docker registry for the read image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the read image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the read image. Overrides `loki.image.tag` + tag: null + # -- The name of the PriorityClass for read pods + priorityClassName: null + # -- Annotations for read deployment + annotations: {} + # -- Annotations for read pods + podAnnotations: {} + # -- Additional labels for each `read` pod + podLabels: {} + # -- Additional selector labels for each `read` pod + selectorLabels: {} + service: + # -- Annotations for read Service + annotations: {} + # -- Additional labels for read Service + labels: {} + # -- Comma-separated list of Loki modules to load for the read + targetModule: "read" + # -- Whether or not to use the 2 target type simple scalable mode (read, write) or the + # 3 target type (read, write, backend). Legacy refers to the 2 target type, so true will + # run two targets, false will run 3 targets. + legacyReadTarget: false + # -- Additional CLI args for the read + extraArgs: [] + # -- Containers to add to the read pods + extraContainers: [] + # -- Environment variables to add to the read pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the read pods + extraEnvFrom: [] + # -- Lifecycle for the read container + lifecycle: {} + # -- Volume mounts to add to the read pods + extraVolumeMounts: [] + # -- Volumes to add to the read pods + extraVolumes: [] + # -- Resource requests and limits for the read + resources: {} + # -- Grace period to allow the read to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for read pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: read + topologyKey: kubernetes.io/hostname + # -- DNS config for read pods + dnsConfig: {} + # -- Node selector for read pods + nodeSelector: {} + # -- Topology Spread Constraints for read pods + topologySpreadConstraints: [] + # -- Tolerations for read pods + tolerations: [] + # -- The default is to deploy all pods in parallel. + podManagementPolicy: "Parallel" + # -- read.persistence is used only if legacyReadTarget is set to true + persistence: + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: true + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Selector for persistent disk + selector: null + # -- Annotations for volume claim + annotations: {} +# -- Configuration for the backend pod(s) +backend: + # -- Number of replicas for the backend + replicas: 3 + autoscaling: + # -- Enable autoscaling for the backend. + enabled: false + # -- Minimum autoscaling replicas for the backend. + minReplicas: 3 + # -- Maximum autoscaling replicas for the backend. + maxReplicas: 6 + # -- Target CPU utilization percentage for the backend. + targetCPUUtilizationPercentage: 60 + # -- Target memory utilization percentage for the backend. + targetMemoryUtilizationPercentage: + # -- Behavior policies while scaling. + behavior: {} + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 60 + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + image: + # -- The Docker registry for the backend image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the backend image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the backend image. Overrides `loki.image.tag` + tag: null + # -- The name of the PriorityClass for backend pods + priorityClassName: null + # -- Annotations for backend StatefulSet + annotations: {} + # -- Annotations for backend pods + podAnnotations: {} + # -- Additional labels for each `backend` pod + podLabels: {} + # -- Additional selector labels for each `backend` pod + selectorLabels: {} + service: + # -- Annotations for backend Service + annotations: {} + # -- Additional labels for backend Service + labels: {} + # -- Comma-separated list of Loki modules to load for the backend + targetModule: "backend" + # -- Additional CLI args for the backend + extraArgs: [] + # -- Environment variables to add to the backend pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the backend pods + extraEnvFrom: [] + # -- Init containers to add to the backend pods + initContainers: [] + # -- Containers to add to the backend pods + extraContainers: [] + # -- Volume mounts to add to the backend pods + extraVolumeMounts: [] + # -- Volumes to add to the backend pods + extraVolumes: [] + # -- Resource requests and limits for the backend + resources: {} + # -- Grace period to allow the backend to shutdown before it is killed. Especially for the ingester, + # this must be increased. It must be long enough so backends can be gracefully shutdown flushing/transferring + # all data and to successfully leave the member ring on shutdown. + terminationGracePeriodSeconds: 300 + # -- Affinity for backend pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: backend + topologyKey: kubernetes.io/hostname + # -- DNS config for backend pods + dnsConfig: {} + # -- Node selector for backend pods + nodeSelector: {} + # -- Topology Spread Constraints for backend pods + topologySpreadConstraints: [] + # -- Tolerations for backend pods + tolerations: [] + # -- The default is to deploy all pods in parallel. + podManagementPolicy: "Parallel" + persistence: + # -- Enable volume claims in pod spec + volumeClaimsEnabled: true + # -- Parameters used for the `data` volume when volumeClaimEnabled if false + dataVolumeParameters: + emptyDir: {} + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: true + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Selector for persistent disk + selector: null + # -- Annotations for volume claim + annotations: {} +###################################################################################################################### +# +# Microservices Mode +# +# For large Loki deployments ingesting more than 1 TB/day +# +###################################################################################################################### + +# -- Configuration for the ingester +ingester: + # -- Number of replicas for the ingester, when zoneAwareReplication.enabled is true, the total + # number of replicas will match this value with each zone having 1/3rd of the total replicas. + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + autoscaling: + # -- Enable autoscaling for the ingester + enabled: false + # -- Minimum autoscaling replicas for the ingester + minReplicas: 1 + # -- Maximum autoscaling replicas for the ingester + maxReplicas: 3 + # -- Target CPU utilisation percentage for the ingester + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the ingester + targetMemoryUtilizationPercentage: null + # -- Allows one to define custom metrics using the HPA/v2 schema (for example, Pods, Object or External metrics) + customMetrics: [] + # - type: Pods + # pods: + # metric: + # name: loki_lines_total + # target: + # type: AverageValue + # averageValue: 10k + behavior: + # -- Enable autoscaling behaviours + enabled: false + # -- define scale down policies, must conform to HPAScalingRules + scaleDown: {} + # -- define scale up policies, must conform to HPAScalingRules + scaleUp: {} + image: + # -- The Docker registry for the ingester image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the ingester image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the ingester image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + priorityClassName: null + # -- Labels for ingester pods + podLabels: {} + # -- Annotations for ingester pods + podAnnotations: {} + # -- The name of the PriorityClass for ingester pods + # -- Labels for ingestor service + serviceLabels: {} + # -- Annotations for ingestor service + serviceAnnotations: {} + # -- Additional CLI args for the ingester + extraArgs: [] + # -- Environment variables to add to the ingester pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the ingester pods + extraEnvFrom: [] + # -- Volume mounts to add to the ingester pods + extraVolumeMounts: [] + # -- Volumes to add to the ingester pods + extraVolumes: [] + # -- Resource requests and limits for the ingester + resources: {} + # -- Containers to add to the ingester pods + extraContainers: [] + # -- Init containers to add to the ingester pods + initContainers: [] + # -- Grace period to allow the ingester to shutdown before it is killed. Especially for the ingestor, + # this must be increased. It must be long enough so ingesters can be gracefully shutdown flushing/transferring + # all data and to successfully leave the member ring on shutdown. + terminationGracePeriodSeconds: 300 + # -- Lifecycle for the ingester container + lifecycle: {} + # -- topologySpread for ingester pods. + # @default -- Defaults to allow skew no more than 1 node + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/component: ingester + # -- Affinity for ingester pods. Ignored if zoneAwareReplication is enabled. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: ingester + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: 1 + # -- Node selector for ingester pods + nodeSelector: {} + # -- Tolerations for ingester pods + tolerations: [] + # -- readiness probe settings for ingester pods. If empty, use `loki.readinessProbe` + readinessProbe: {} + # -- liveness probe settings for ingester pods. If empty use `loki.livenessProbe` + livenessProbe: {} + # -- UpdateStrategy for the ingester StatefulSets. + updateStrategy: + # -- One of 'OnDelete' or 'RollingUpdate' + type: RollingUpdate + # -- Optional for updateStrategy.type=RollingUpdate. See [Partitioned rolling updates](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions) in the StatefulSet docs for details. + # rollingUpdate: + # partition: 0 + persistence: + # -- Enable creating PVCs which is required when using boltdb-shipper + enabled: false + # -- Use emptyDir with ramdisk for storage. **Please note that all data in ingester will be lost on pod restart** + inMemory: false + # -- List of the ingester PVCs + # @notationType -- list + claims: + - name: data + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # - name: wal + # size: 150Gi + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + whenDeleted: Retain + whenScaled: Retain + # -- Adds the appProtocol field to the ingester service. This allows ingester to work with istio protocol selection. + appProtocol: + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + grpc: "" + # -- Enabling zone awareness on ingesters will create 3 statefulests where all writes will send a replica to each zone. + # This is primarily intended to accelerate rollout operations by allowing for multiple ingesters within a single + # zone to be shutdown and restart simultaneously (the remaining 2 zones will be guaranteed to have at least one copy + # of the data). + # Note: This can be used to run Loki over multiple cloud provider availability zones however this is not currently + # recommended as Loki is not optimized for this and cross zone network traffic costs can become extremely high + # extremely quickly. Even with zone awareness enabled, it is recommended to run Loki in a single availability zone. + zoneAwareReplication: + # -- Enable zone awareness. + enabled: true + # -- The percent of replicas in each zone that will be restarted at once. In a value of 0-100 + maxUnavailablePct: 33 + # -- zoneA configuration + zoneA: + # -- optionally define a node selector for this zone + nodeSelector: null + # -- optionally define extra affinity rules, by default different zones are not allowed to schedule on the same host + extraAffinity: {} + # -- Specific annotations to add to zone A statefulset + annotations: {} + # -- Specific annotations to add to zone A pods + podAnnotations: {} + zoneB: + # -- optionally define a node selector for this zone + nodeSelector: null + # -- optionally define extra affinity rules, by default different zones are not allowed to schedule on the same host + extraAffinity: {} + # -- Specific annotations to add to zone B statefulset + annotations: {} + # -- Specific annotations to add to zone B pods + podAnnotations: {} + zoneC: + # -- optionally define a node selector for this zone + nodeSelector: null + # -- optionally define extra affinity rules, by default different zones are not allowed to schedule on the same host + extraAffinity: {} + # -- Specific annotations to add to zone C statefulset + annotations: {} + # -- Specific annotations to add to zone C pods + podAnnotations: {} + # -- The migration block allows migrating non zone aware ingesters to zone aware ingesters. + migration: + enabled: false + excludeDefaultZone: false + readPath: false + writePath: false + + # optionally allow adding arbitrary prefix to the ingester rollout-group label + rolloutGroupPrefix: null + # optionally allow adding 'loki-' prefix to ingester name label + addIngesterNamePrefix: false + +# -- Configuration for the distributor +distributor: + # -- Number of replicas for the distributor + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + autoscaling: + # -- Enable autoscaling for the distributor + enabled: false + # -- Minimum autoscaling replicas for the distributor + minReplicas: 1 + # -- Maximum autoscaling replicas for the distributor + maxReplicas: 3 + # -- Target CPU utilisation percentage for the distributor + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the distributor + targetMemoryUtilizationPercentage: null + # -- Allows one to define custom metrics using the HPA/v2 schema (for example, Pods, Object or External metrics) + customMetrics: [] + # - type: Pods + # pods: + # metric: + # name: loki_lines_total + # target: + # type: AverageValue + # averageValue: 10k + behavior: + # -- Enable autoscaling behaviours + enabled: false + # -- define scale down policies, must conform to HPAScalingRules + scaleDown: {} + # -- define scale up policies, must conform to HPAScalingRules + scaleUp: {} + image: + # -- The Docker registry for the distributor image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the distributor image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the distributor image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for distributor pods + priorityClassName: null + # -- Labels for distributor pods + podLabels: {} + # -- Annotations for distributor pods + podAnnotations: {} + # -- Labels for distributor service + serviceLabels: {} + # -- Annotations for distributor service + serviceAnnotations: {} + # -- Additional CLI args for the distributor + extraArgs: [] + # -- Environment variables to add to the distributor pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the distributor pods + extraEnvFrom: [] + # -- Volume mounts to add to the distributor pods + extraVolumeMounts: [] + # -- Volumes to add to the distributor pods + extraVolumes: [] + # -- Resource requests and limits for the distributor + resources: {} + # -- Containers to add to the distributor pods + extraContainers: [] + # -- Grace period to allow the distributor to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for distributor pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: distributor + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Max Surge for distributor pods + maxSurge: 0 + # -- Node selector for distributor pods + nodeSelector: {} + # -- Topology Spread Constraints for distributor pods + topologySpreadConstraints: [] + # -- Tolerations for distributor pods + tolerations: [] + # -- Adds the appProtocol field to the distributor service. This allows distributor to work with istio protocol selection. + appProtocol: + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + grpc: "" +# -- Configuration for the querier +querier: + # -- Number of replicas for the querier + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + autoscaling: + # -- Enable autoscaling for the querier, this is only used if `indexGateway.enabled: true` + enabled: false + # -- Minimum autoscaling replicas for the querier + minReplicas: 1 + # -- Maximum autoscaling replicas for the querier + maxReplicas: 3 + # -- Target CPU utilisation percentage for the querier + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the querier + targetMemoryUtilizationPercentage: null + # -- Allows one to define custom metrics using the HPA/v2 schema (for example, Pods, Object or External metrics) + customMetrics: [] + # - type: External + # external: + # metric: + # name: loki_inflight_queries + # target: + # type: AverageValue + # averageValue: 12 + behavior: + # -- Enable autoscaling behaviours + enabled: false + # -- define scale down policies, must conform to HPAScalingRules + scaleDown: {} + # -- define scale up policies, must conform to HPAScalingRules + scaleUp: {} + image: + # -- The Docker registry for the querier image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the querier image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the querier image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for querier pods + priorityClassName: null + # -- Labels for querier pods + podLabels: {} + # -- Annotations for querier pods + podAnnotations: {} + # -- Labels for querier service + serviceLabels: {} + # -- Annotations for querier service + serviceAnnotations: {} + # -- Additional CLI args for the querier + extraArgs: [] + # -- Environment variables to add to the querier pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the querier pods + extraEnvFrom: [] + # -- Volume mounts to add to the querier pods + extraVolumeMounts: [] + # -- Volumes to add to the querier pods + extraVolumes: [] + # -- Resource requests and limits for the querier + resources: {} + # -- Containers to add to the querier pods + extraContainers: [] + # -- Init containers to add to the querier pods + initContainers: [] + # -- Grace period to allow the querier to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- topologySpread for querier pods. + # @default -- Defaults to allow skew no more then 1 node + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/component: querier + # -- Affinity for querier pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: querier + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Max Surge for querier pods + maxSurge: 0 + # -- Node selector for querier pods + nodeSelector: {} + # -- Tolerations for querier pods + tolerations: [] + # -- DNSConfig for querier pods + dnsConfig: {} + persistence: + # -- Enable creating PVCs for the querier cache + enabled: false + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Annotations for querier PVCs + annotations: {} + # -- Adds the appProtocol field to the querier service. This allows querier to work with istio protocol selection. + appProtocol: + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + grpc: "" +# -- Configuration for the query-frontend +queryFrontend: + # -- Number of replicas for the query-frontend + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + autoscaling: + # -- Enable autoscaling for the query-frontend + enabled: false + # -- Minimum autoscaling replicas for the query-frontend + minReplicas: 1 + # -- Maximum autoscaling replicas for the query-frontend + maxReplicas: 3 + # -- Target CPU utilisation percentage for the query-frontend + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the query-frontend + targetMemoryUtilizationPercentage: null + # -- Allows one to define custom metrics using the HPA/v2 schema (for example, Pods, Object or External metrics) + customMetrics: [] + # - type: Pods + # pods: + # metric: + # name: loki_query_rate + # target: + # type: AverageValue + # averageValue: 100 + behavior: + # -- Enable autoscaling behaviours + enabled: false + # -- define scale down policies, must conform to HPAScalingRules + scaleDown: {} + # -- define scale up policies, must conform to HPAScalingRules + scaleUp: {} + image: + # -- The Docker registry for the query-frontend image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the query-frontend image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the query-frontend image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for query-frontend pods + priorityClassName: null + # -- Labels for query-frontend pods + podLabels: {} + # -- Annotations for query-frontend pods + podAnnotations: {} + # -- Labels for query-frontend service + serviceLabels: {} + # -- Annotations for query-frontend service + serviceAnnotations: {} + # -- Additional CLI args for the query-frontend + extraArgs: [] + # -- Environment variables to add to the query-frontend pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the query-frontend pods + extraEnvFrom: [] + # -- Volume mounts to add to the query-frontend pods + extraVolumeMounts: [] + # -- Volumes to add to the query-frontend pods + extraVolumes: [] + # -- Resource requests and limits for the query-frontend + resources: {} + # -- Containers to add to the query-frontend pods + extraContainers: [] + # -- Grace period to allow the query-frontend to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for query-frontend pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: query-frontend + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Node selector for query-frontend pods + nodeSelector: {} + # -- Topology Spread Constraints for query-frontend pods + topologySpreadConstraints: [] + # -- Tolerations for query-frontend pods + tolerations: [] + # -- Adds the appProtocol field to the queryFrontend service. This allows queryFrontend to work with istio protocol selection. + appProtocol: + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + grpc: "" +# -- Configuration for the query-scheduler +queryScheduler: + # -- Number of replicas for the query-scheduler. + # It should be lower than `-querier.max-concurrent` to avoid generating back-pressure in queriers; + # it's also recommended that this value evenly divides the latter + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the query-scheduler image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the query-scheduler image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the query-scheduler image. Overrides `loki.image.tag` + tag: null + # -- The name of the PriorityClass for query-scheduler pods + priorityClassName: null + # -- Labels for query-scheduler pods + podLabels: {} + # -- Annotations for query-scheduler pods + podAnnotations: {} + # -- Labels for query-scheduler service + serviceLabels: {} + # -- Annotations for query-scheduler service + serviceAnnotations: {} + # -- Additional CLI args for the query-scheduler + extraArgs: [] + # -- Environment variables to add to the query-scheduler pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the query-scheduler pods + extraEnvFrom: [] + # -- Volume mounts to add to the query-scheduler pods + extraVolumeMounts: [] + # -- Volumes to add to the query-scheduler pods + extraVolumes: [] + # -- Resource requests and limits for the query-scheduler + resources: {} + # -- Containers to add to the query-scheduler pods + extraContainers: [] + # -- Grace period to allow the query-scheduler to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for query-scheduler pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: query-scheduler + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: 1 + # -- Node selector for query-scheduler pods + nodeSelector: {} + # -- Topology Spread Constraints for query-scheduler pods + topologySpreadConstraints: [] + # -- Tolerations for query-scheduler pods + tolerations: [] + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" +# -- Configuration for the index-gateway +indexGateway: + # -- Number of replicas for the index-gateway + replicas: 0 + # -- Whether the index gateway should join the memberlist hashring + joinMemberlist: true + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the index-gateway image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the index-gateway image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the index-gateway image. Overrides `loki.image.tag` + tag: null + # -- The name of the PriorityClass for index-gateway pods + priorityClassName: null + # -- Labels for index-gateway pods + podLabels: {} + # -- Annotations for index-gateway pods + podAnnotations: {} + # -- Labels for index-gateway service + serviceLabels: {} + # -- Annotations for index-gateway service + serviceAnnotations: {} + # -- Additional CLI args for the index-gateway + extraArgs: [] + # -- Environment variables to add to the index-gateway pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the index-gateway pods + extraEnvFrom: [] + # -- Volume mounts to add to the index-gateway pods + extraVolumeMounts: [] + # -- Volumes to add to the index-gateway pods + extraVolumes: [] + # -- Resource requests and limits for the index-gateway + resources: {} + # -- Containers to add to the index-gateway pods + extraContainers: [] + # -- Init containers to add to the index-gateway pods + initContainers: [] + # -- Grace period to allow the index-gateway to shutdown before it is killed. + terminationGracePeriodSeconds: 300 + # -- Affinity for index-gateway pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: index-gateway + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Node selector for index-gateway pods + nodeSelector: {} + # -- Topology Spread Constraints for index-gateway pods + topologySpreadConstraints: [] + # -- Tolerations for index-gateway pods + tolerations: [] + persistence: + # -- Enable creating PVCs which is required when using boltdb-shipper + enabled: false + # -- Use emptyDir with ramdisk for storage. **Please note that all data in indexGateway will be lost on pod restart** + inMemory: false + # -- Size of persistent or memory disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Annotations for index gateway PVCs + annotations: {} + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + whenDeleted: Retain + whenScaled: Retain + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + # -- UpdateStrategy for the indexGateway StatefulSet. + updateStrategy: + # -- One of 'OnDelete' or 'RollingUpdate' + type: RollingUpdate + # -- Optional for updateStrategy.type=RollingUpdate. See [Partitioned rolling updates](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions) in the StatefulSet docs for details. + # rollingUpdate: + # partition: 0 +# -- Configuration for the compactor +compactor: + # -- Number of replicas for the compactor + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the compactor image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the compactor image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the compactor image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for compactor pods + priorityClassName: null + # -- Labels for compactor pods + podLabels: {} + # -- Annotations for compactor pods + podAnnotations: {} + # -- Affinity for compactor pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: compactor + topologyKey: kubernetes.io/hostname + # -- Labels for compactor service + serviceLabels: {} + # -- Annotations for compactor service + serviceAnnotations: {} + # -- Additional CLI args for the compactor + extraArgs: [] + # -- Environment variables to add to the compactor pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the compactor pods + extraEnvFrom: [] + # -- Volume mounts to add to the compactor pods + extraVolumeMounts: [] + # -- Volumes to add to the compactor pods + extraVolumes: [] + # -- readiness probe settings for ingester pods. If empty, use `loki.readinessProbe` + readinessProbe: {} + # -- liveness probe settings for ingester pods. If empty use `loki.livenessProbe` + livenessProbe: {} + # -- Resource requests and limits for the compactor + resources: {} + # -- Containers to add to the compactor pods + extraContainers: [] + # -- Init containers to add to the compactor pods + initContainers: [] + # -- Grace period to allow the compactor to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Node selector for compactor pods + nodeSelector: {} + # -- Tolerations for compactor pods + tolerations: [] + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + persistence: + # -- Enable creating PVCs for the compactor + enabled: false + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Annotations for compactor PVCs + annotations: {} + # -- List of the compactor PVCs + # @notationType -- list + claims: + - name: data + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # - name: wal + # size: 150Gi + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + whenDeleted: Retain + whenScaled: Retain + serviceAccount: + create: false + # -- The name of the ServiceAccount to use for the compactor. + # If not set and create is true, a name is generated by appending + # "-compactor" to the common ServiceAccount. + name: null + # -- Image pull secrets for the compactor service account + imagePullSecrets: [] + # -- Annotations for the compactor service account + annotations: {} + # -- Set this toggle to false to opt out of automounting API credentials for the service account + automountServiceAccountToken: true +# -- Configuration for the bloom-gateway +bloomGateway: + # -- Number of replicas for the bloom-gateway + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the bloom-gateway image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the bloom-gateway image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the bloom-gateway image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for bloom-gateway pods + priorityClassName: null + # -- Labels for bloom-gateway pods + podLabels: {} + # -- Annotations for bloom-gateway pods + podAnnotations: {} + # -- Affinity for bloom-gateway pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: bloom-gateway + topologyKey: kubernetes.io/hostname + # -- Labels for bloom-gateway service + serviceLabels: {} + # -- Annotations for bloom-gateway service + serviceAnnotations: {} + # -- Additional CLI args for the bloom-gateway + extraArgs: [] + # -- Environment variables to add to the bloom-gateway pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the bloom-gateway pods + extraEnvFrom: [] + # -- Volume mounts to add to the bloom-gateway pods + extraVolumeMounts: [] + # -- Volumes to add to the bloom-gateway pods + extraVolumes: [] + # -- readiness probe settings for ingester pods. If empty, use `loki.readinessProbe` + readinessProbe: {} + # -- liveness probe settings for ingester pods. If empty use `loki.livenessProbe` + livenessProbe: {} + # -- Resource requests and limits for the bloom-gateway + resources: {} + # -- Containers to add to the bloom-gateway pods + extraContainers: [] + # -- Init containers to add to the bloom-gateway pods + initContainers: [] + # -- Grace period to allow the bloom-gateway to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Node selector for bloom-gateway pods + nodeSelector: {} + # -- Tolerations for bloom-gateway pods + tolerations: [] + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + persistence: + # -- Enable creating PVCs for the bloom-gateway + enabled: false + # -- Annotations for bloom-gateway PVCs + annotations: {} + # -- List of the bloom-gateway PVCs + # @notationType -- list + claims: + - name: data + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + whenDeleted: Retain + whenScaled: Retain + serviceAccount: + create: false + # -- The name of the ServiceAccount to use for the bloom-gateway. + # If not set and create is true, a name is generated by appending + # "-bloom-gateway" to the common ServiceAccount. + name: null + # -- Image pull secrets for the bloom-gateway service account + imagePullSecrets: [] + # -- Annotations for the bloom-gateway service account + annotations: {} + # -- Set this toggle to false to opt out of automounting API credentials for the service account + automountServiceAccountToken: true +# -- Configuration for the bloom-planner +bloomPlanner: + # -- Number of replicas for the bloom-planner + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the bloom-planner image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the bloom-planner image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the bloom-planner image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for bloom-planner pods + priorityClassName: null + # -- Labels for bloom-planner pods + podLabels: {} + # -- Annotations for bloom-planner pods + podAnnotations: {} + # -- Affinity for bloom-planner pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: bloom-planner + topologyKey: kubernetes.io/hostname + # -- Labels for bloom-planner service + serviceLabels: {} + # -- Annotations for bloom-planner service + serviceAnnotations: {} + # -- Additional CLI args for the bloom-planner + extraArgs: [] + # -- Environment variables to add to the bloom-planner pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the bloom-planner pods + extraEnvFrom: [] + # -- Volume mounts to add to the bloom-planner pods + extraVolumeMounts: [] + # -- Volumes to add to the bloom-planner pods + extraVolumes: [] + # -- readiness probe settings for ingester pods. If empty, use `loki.readinessProbe` + readinessProbe: {} + # -- liveness probe settings for ingester pods. If empty use `loki.livenessProbe` + livenessProbe: {} + # -- Resource requests and limits for the bloom-planner + resources: {} + # -- Containers to add to the bloom-planner pods + extraContainers: [] + # -- Init containers to add to the bloom-planner pods + initContainers: [] + # -- Grace period to allow the bloom-planner to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Node selector for bloom-planner pods + nodeSelector: {} + # -- Tolerations for bloom-planner pods + tolerations: [] + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + persistence: + # -- Enable creating PVCs for the bloom-planner + enabled: false + # -- Annotations for bloom-planner PVCs + annotations: {} + # -- List of the bloom-planner PVCs + # @notationType -- list + claims: + - name: data + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + whenDeleted: Retain + whenScaled: Retain + serviceAccount: + create: false + # -- The name of the ServiceAccount to use for the bloom-planner. + # If not set and create is true, a name is generated by appending + # "-bloom-planner" to the common ServiceAccount. + name: null + # -- Image pull secrets for the bloom-planner service account + imagePullSecrets: [] + # -- Annotations for the bloom-planner service account + annotations: {} + # -- Set this toggle to false to opt out of automounting API credentials for the service account + automountServiceAccountToken: true +# -- Configuration for the bloom-builder +bloomBuilder: + # -- Number of replicas for the bloom-builder + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + autoscaling: + # -- Enable autoscaling for the bloom-builder + enabled: false + # -- Minimum autoscaling replicas for the bloom-builder + minReplicas: 1 + # -- Maximum autoscaling replicas for the bloom-builder + maxReplicas: 3 + # -- Target CPU utilisation percentage for the bloom-builder + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the bloom-builder + targetMemoryUtilizationPercentage: null + # -- Allows one to define custom metrics using the HPA/v2 schema (for example, Pods, Object or External metrics) + customMetrics: [] + # - type: Pods + # pods: + # metric: + # name: loki_query_rate + # target: + # type: AverageValue + # averageValue: 100 + behavior: + # -- Enable autoscaling behaviours + enabled: false + # -- define scale down policies, must conform to HPAScalingRules + scaleDown: {} + # -- define scale up policies, must conform to HPAScalingRules + scaleUp: {} + image: + # -- The Docker registry for the bloom-builder image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the bloom-builder image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the bloom-builder image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for bloom-builder pods + priorityClassName: null + # -- Labels for bloom-builder pods + podLabels: {} + # -- Annotations for bloom-builder pods + podAnnotations: {} + # -- Labels for bloom-builder service + serviceLabels: {} + # -- Annotations for bloom-builder service + serviceAnnotations: {} + # -- Additional CLI args for the bloom-builder + extraArgs: [] + # -- Environment variables to add to the bloom-builder pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the bloom-builder pods + extraEnvFrom: [] + # -- Volume mounts to add to the bloom-builder pods + extraVolumeMounts: [] + # -- Volumes to add to the bloom-builder pods + extraVolumes: [] + # -- Resource requests and limits for the bloom-builder + resources: {} + # -- Containers to add to the bloom-builder pods + extraContainers: [] + # -- Grace period to allow the bloom-builder to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for bloom-builder pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: bloom-builder + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Node selector for bloom-builder pods + nodeSelector: {} + # -- Tolerations for bloom-builder pods + tolerations: [] + # -- Adds the appProtocol field to the queryFrontend service. This allows bloomBuilder to work with istio protocol selection. + appProtocol: + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + grpc: "" +# -- Configuration for the pattern ingester +patternIngester: + # -- Number of replicas for the pattern ingester + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the pattern ingester image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the pattern ingester image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the pattern ingester image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for pattern ingester pods + priorityClassName: null + # -- Labels for pattern ingester pods + podLabels: {} + # -- Annotations for pattern ingester pods + podAnnotations: {} + # -- Affinity for pattern ingester pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: pattern-ingester + topologyKey: kubernetes.io/hostname + # -- Labels for pattern ingester service + serviceLabels: {} + # -- Annotations for pattern ingester service + serviceAnnotations: {} + # -- Additional CLI args for the pattern ingester + extraArgs: [] + # -- Environment variables to add to the pattern ingester pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the pattern ingester pods + extraEnvFrom: [] + # -- Volume mounts to add to the pattern ingester pods + extraVolumeMounts: [] + # -- Volumes to add to the pattern ingester pods + extraVolumes: [] + # -- readiness probe settings for ingester pods. If empty, use `loki.readinessProbe` + readinessProbe: {} + # -- liveness probe settings for ingester pods. If empty use `loki.livenessProbe` + livenessProbe: {} + # -- Resource requests and limits for the pattern ingester + resources: {} + # -- Containers to add to the pattern ingester pods + extraContainers: [] + # -- Init containers to add to the pattern ingester pods + initContainers: [] + # -- Grace period to allow the pattern ingester to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Node selector for pattern ingester pods + nodeSelector: {} + # -- Topology Spread Constraints for pattern ingester pods + topologySpreadConstraints: [] + # -- Tolerations for pattern ingester pods + tolerations: [] + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + persistence: + # -- Enable creating PVCs for the pattern ingester + enabled: false + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Annotations for pattern ingester PVCs + annotations: {} + # -- List of the pattern ingester PVCs + # @notationType -- list + claims: + - name: data + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # - name: wal + # size: 150Gi + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + whenDeleted: Retain + whenScaled: Retain + serviceAccount: + create: false + # -- The name of the ServiceAccount to use for the pattern ingester. + # If not set and create is true, a name is generated by appending + # "-pattern-ingester" to the common ServiceAccount. + name: null + # -- Image pull secrets for the pattern ingester service account + imagePullSecrets: [] + # -- Annotations for the pattern ingester service account + annotations: {} + # -- Set this toggle to false to opt out of automounting API credentials for the service account + automountServiceAccountToken: true +# -- Configuration for the ruler +ruler: + # -- The ruler component is optional and can be disabled if desired. + enabled: true + # -- Number of replicas for the ruler + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the ruler image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the ruler image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the ruler image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for ruler pods + priorityClassName: null + # -- Labels for compactor pods + podLabels: {} + # -- Annotations for ruler pods + podAnnotations: {} + # -- Labels for ruler service + serviceLabels: {} + # -- Annotations for ruler service + serviceAnnotations: {} + # -- Additional CLI args for the ruler + extraArgs: [] + # -- Environment variables to add to the ruler pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the ruler pods + extraEnvFrom: [] + # -- Volume mounts to add to the ruler pods + extraVolumeMounts: [] + # -- Volumes to add to the ruler pods + extraVolumes: [] + # -- Resource requests and limits for the ruler + resources: {} + # -- Containers to add to the ruler pods + extraContainers: [] + # -- Init containers to add to the ruler pods + initContainers: [] + # -- Grace period to allow the ruler to shutdown before it is killed + terminationGracePeriodSeconds: 300 + # -- Affinity for ruler pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: ruler + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Node selector for ruler pods + nodeSelector: {} + # -- Topology Spread Constraints for ruler pods + topologySpreadConstraints: [] + # -- Tolerations for ruler pods + tolerations: [] + # -- DNSConfig for ruler pods + dnsConfig: {} + persistence: + # -- Enable creating PVCs which is required when using recording rules + enabled: false + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Annotations for ruler PVCs + annotations: {} + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + # -- Directories containing rules files + directories: {} + # tenant_foo: + # rules1.txt: | + # groups: + # - name: should_fire + # rules: + # - alert: HighPercentageError + # expr: | + # sum(rate({app="foo", env="production"} |= "error" [5m])) by (job) + # / + # sum(rate({app="foo", env="production"}[5m])) by (job) + # > 0.05 + # for: 10m + # labels: + # severity: warning + # annotations: + # summary: High error rate + # - name: credentials_leak + # rules: + # - alert: http-credentials-leaked + # annotations: + # message: "{{ $labels.job }} is leaking http basic auth credentials." + # expr: 'sum by (cluster, job, pod) (count_over_time({namespace="prod"} |~ "http(s?)://(\\w+):(\\w+)@" [5m]) > 0)' + # for: 10m + # labels: + # severity: critical + # rules2.txt: | + # groups: + # - name: example + # rules: + # - alert: HighThroughputLogStreams + # expr: sum by(container) (rate({job=~"loki-dev/.*"}[1m])) > 1000 + # for: 2m + # tenant_bar: + # rules1.txt: | + # groups: + # - name: should_fire + # rules: + # - alert: HighPercentageError + # expr: | + # sum(rate({app="foo", env="production"} |= "error" [5m])) by (job) + # / + # sum(rate({app="foo", env="production"}[5m])) by (job) + # > 0.05 + # for: 10m + # labels: + # severity: warning + # annotations: + # summary: High error rate + # - name: credentials_leak + # rules: + # - alert: http-credentials-leaked + # annotations: + # message: "{{ $labels.job }} is leaking http basic auth credentials." + # expr: 'sum by (cluster, job, pod) (count_over_time({namespace="prod"} |~ "http(s?)://(\\w+):(\\w+)@" [5m]) > 0)' + # for: 10m + # labels: + # severity: critical + # rules2.txt: | + # groups: + # - name: example + # rules: + # - alert: HighThroughputLogStreams + # expr: sum by(container) (rate({job=~"loki-dev/.*"}[1m])) > 1000 + # for: 2m + +# -- Configuration for the overrides-exporter +overridesExporter: + # -- The overrides-exporter component is optional and can be disabled if desired. + enabled: false + # -- Number of replicas for the overrides-exporter + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the overrides-exporter image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the overrides-exporter image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the overrides-exporter image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for overrides-exporter pods + priorityClassName: null + # -- Labels for overrides-exporter pods + podLabels: {} + # -- Annotations for overrides-exporter pods + podAnnotations: {} + # -- Labels for overrides-exporter service + serviceLabels: {} + # -- Annotations for overrides-exporter service + serviceAnnotations: {} + # -- Additional CLI args for the overrides-exporter + extraArgs: [] + # -- Environment variables to add to the overrides-exporter pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the overrides-exporter pods + extraEnvFrom: [] + # -- Volume mounts to add to the overrides-exporter pods + extraVolumeMounts: [] + # -- Volumes to add to the overrides-exporter pods + extraVolumes: [] + # -- Resource requests and limits for the overrides-exporter + resources: {} + # -- Containers to add to the overrides-exporter pods + extraContainers: [] + # -- Init containers to add to the overrides-exporter pods + initContainers: [] + # -- Grace period to allow the overrides-exporter to shutdown before it is killed + terminationGracePeriodSeconds: 300 + # -- Affinity for overrides-exporter pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: overrides-exporter + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Node selector for overrides-exporter pods + nodeSelector: {} + # -- Topology Spread Constraints for overrides-exporter pods + topologySpreadConstraints: [] + # -- Tolerations for overrides-exporter pods + tolerations: [] + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + +memcached: + image: + # -- Memcached Docker image repository + repository: memcached + # -- Memcached Docker image tag + tag: 1.6.38-alpine + # -- Memcached Docker image pull policy + pullPolicy: IfNotPresent + # -- The SecurityContext override for memcached pods + podSecurityContext: + runAsNonRoot: true + runAsUser: 11211 + runAsGroup: 11211 + fsGroup: 11211 + # -- The name of the PriorityClass for memcached pods + priorityClassName: null + # -- The SecurityContext for memcached containers + containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: [ALL] + allowPrivilegeEscalation: false +memcachedExporter: + # -- Whether memcached metrics should be exported + enabled: true + image: + repository: prom/memcached-exporter + tag: v0.15.2 + pullPolicy: IfNotPresent + resources: + requests: {} + limits: {} + # -- The SecurityContext for memcached exporter containers + containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: [ALL] + allowPrivilegeEscalation: false + # -- Extra args to add to the exporter container. + # Example: + # extraArgs: + # memcached.tls.enable: true + # memcached.tls.cert-file: /certs/cert.crt + # memcached.tls.key-file: /certs/cert.key + # memcached.tls.ca-file: /certs/ca.crt + # memcached.tls.insecure-skip-verify: false + # memcached.tls.server-name: memcached + extraArgs: {} +resultsCache: + # -- Specifies whether memcached based results-cache should be enabled + enabled: true + # -- Specify how long cached results should be stored in the results-cache before being expired + defaultValidity: 12h + # -- Memcached operation timeout + timeout: 500ms + # -- Total number of results-cache replicas + replicas: 1 + # -- Port of the results-cache service + port: 11211 + # -- Amount of memory allocated to results-cache for object storage (in MB). + allocatedMemory: 1024 + # -- Maximum item results-cache for memcached (in MB). + maxItemMemory: 5 + # -- Maximum number of connections allowed + connectionLimit: 16384 + # -- Max memory to use for cache write back + writebackSizeLimit: 500MB + # -- Max number of objects to use for cache write back + writebackBuffer: 500000 + # -- Number of parallel threads for cache write back + writebackParallelism: 1 + # -- Extra init containers for results-cache pods + initContainers: [] + # -- Annotations for the results-cache pods + annotations: {} + # -- Node selector for results-cache pods + nodeSelector: {} + # -- Affinity for results-cache pods + affinity: {} + # -- topologySpreadConstraints allows to customize the default topologySpreadConstraints. This can be either a single dict as shown below or a slice of topologySpreadConstraints. + # labelSelector is taken from the constraint itself (if it exists) or is generated by the chart using the same selectors as for services. + topologySpreadConstraints: [] + # maxSkew: 1 + # topologyKey: kubernetes.io/hostname + # whenUnsatisfiable: ScheduleAnyway + # -- Tolerations for results-cache pods + tolerations: [] + # -- Pod Disruption Budget + podDisruptionBudget: + maxUnavailable: 1 + # -- The name of the PriorityClass for results-cache pods + priorityClassName: null + # -- Labels for results-cache pods + podLabels: {} + # -- Annotations for results-cache pods + podAnnotations: {} + # -- Management policy for results-cache pods + podManagementPolicy: Parallel + # -- Grace period to allow the results-cache to shutdown before it is killed + terminationGracePeriodSeconds: 60 + # -- Stateful results-cache strategy + statefulStrategy: + type: RollingUpdate + # -- Add extended options for results-cache memcached container. The format is the same as for the memcached -o/--extend flag. + # Example: + # extraExtendedOptions: 'tls,modern,track_sizes' + extraExtendedOptions: "" + # -- Additional CLI args for results-cache + extraArgs: {} + # -- Additional containers to be added to the results-cache pod. + extraContainers: [] + # -- Additional volumes to be added to the results-cache pod (applies to both memcached and exporter containers). + # Example: + # extraVolumes: + # - name: extra-volume + # secret: + # secretName: extra-volume-secret + extraVolumes: [] + # -- Additional volume mounts to be added to the results-cache pod (applies to both memcached and exporter containers). + # Example: + # extraVolumeMounts: + # - name: extra-volume + # mountPath: /etc/extra-volume + # readOnly: true + extraVolumeMounts: [] + # -- Resource requests and limits for the results-cache + # By default a safe memory limit will be requested based on allocatedMemory value (floor (* 1.2 allocatedMemory)). + resources: null + # -- Service annotations and labels + service: + annotations: {} + labels: {} + # -- Persistence settings for the results-cache + persistence: + # -- Enable creating PVCs for the results-cache + enabled: false + # -- Size of persistent disk, must be in G or Gi + storageSize: 10G + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Volume mount path + mountPath: /data +chunksCache: + # -- Specifies whether memcached based chunks-cache should be enabled + enabled: true + # -- Batchsize for sending and receiving chunks from chunks cache + batchSize: 4 + # -- Parallel threads for sending and receiving chunks from chunks cache + parallelism: 5 + # -- Memcached operation timeout + timeout: 2000ms + # -- Specify how long cached chunks should be stored in the chunks-cache before being expired + defaultValidity: 0s + # -- Total number of chunks-cache replicas + replicas: 1 + # -- Port of the chunks-cache service + port: 11211 + # -- Amount of memory allocated to chunks-cache for object storage (in MB). + allocatedMemory: 8192 + # -- Maximum item memory for chunks-cache (in MB). + maxItemMemory: 5 + # -- Maximum number of connections allowed + connectionLimit: 16384 + # -- Max memory to use for cache write back + writebackSizeLimit: 500MB + # -- Max number of objects to use for cache write back + writebackBuffer: 500000 + # -- Number of parallel threads for cache write back + writebackParallelism: 1 + # -- Extra init containers for chunks-cache pods + initContainers: [] + # -- Annotations for the chunks-cache pods + annotations: {} + # -- Node selector for chunks-cache pods + nodeSelector: {} + # -- Affinity for chunks-cache pods + affinity: {} + # -- topologySpreadConstraints allows to customize the default topologySpreadConstraints. This can be either a single dict as shown below or a slice of topologySpreadConstraints. + # labelSelector is taken from the constraint itself (if it exists) or is generated by the chart using the same selectors as for services. + topologySpreadConstraints: [] + # maxSkew: 1 + # topologyKey: kubernetes.io/hostname + # whenUnsatisfiable: ScheduleAnyway + # -- Tolerations for chunks-cache pods + tolerations: [] + # -- Pod Disruption Budget + podDisruptionBudget: + maxUnavailable: 1 + # -- The name of the PriorityClass for chunks-cache pods + priorityClassName: null + # -- Labels for chunks-cache pods + podLabels: {} + # -- Annotations for chunks-cache pods + podAnnotations: {} + # -- Management policy for chunks-cache pods + podManagementPolicy: Parallel + # -- Grace period to allow the chunks-cache to shutdown before it is killed + terminationGracePeriodSeconds: 60 + # -- Stateful chunks-cache strategy + statefulStrategy: + type: RollingUpdate + # -- Add extended options for chunks-cache memcached container. The format is the same as for the memcached -o/--extend flag. + # Example: + # extraExtendedOptions: 'tls,no_hashexpand' + extraExtendedOptions: "" + # -- Additional CLI args for chunks-cache + extraArgs: {} + # -- Additional containers to be added to the chunks-cache pod. + extraContainers: [] + # -- Additional volumes to be added to the chunks-cache pod (applies to both memcached and exporter containers). + # Example: + # extraVolumes: + # - name: extra-volume + # secret: + # secretName: extra-volume-secret + extraVolumes: [] + # -- Additional volume mounts to be added to the chunks-cache pod (applies to both memcached and exporter containers). + # Example: + # extraVolumeMounts: + # - name: extra-volume + # mountPath: /etc/extra-volume + # readOnly: true + extraVolumeMounts: [] + # -- Resource requests and limits for the chunks-cache + # By default a safe memory limit will be requested based on allocatedMemory value (floor (* 1.2 allocatedMemory)). + resources: null + # -- Service annotations and labels + service: + annotations: {} + labels: {} + # -- Persistence settings for the chunks-cache + persistence: + # -- Enable creating PVCs for the chunks-cache + enabled: false + # -- Size of persistent disk, must be in G or Gi + storageSize: 10G + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Volume mount path + mountPath: /data +###################################################################################################################### +# +# Subchart configurations +# +###################################################################################################################### +# -- Setting for the Grafana Rollout Operator https://github.com/grafana/helm-charts/tree/main/charts/rollout-operator +rollout_operator: + enabled: false + # -- podSecurityContext is the pod security context for the rollout operator. + # When installing on OpenShift, override podSecurityContext settings with + # + # rollout_operator: + # podSecurityContext: + # fsGroup: null + # runAsGroup: null + # runAsUser: null + podSecurityContext: + fsGroup: 10001 + runAsGroup: 10001 + runAsNonRoot: true + runAsUser: 10001 + seccompProfile: + type: RuntimeDefault + # Set the container security context + securityContext: + readOnlyRootFilesystem: true + capabilities: + drop: [ALL] + allowPrivilegeEscalation: false +# -- Configuration for the minio subchart +minio: + enabled: false + replicas: 1 + # Minio requires 2 to 16 drives for erasure code (drivesPerNode * replicas) + # https://docs.min.io/docs/minio-erasure-code-quickstart-guide + # Since we only have 1 replica, that means 2 drives must be used. + drivesPerNode: 2 + # root user; not used for GEL authentication + rootUser: root-user + rootPassword: supersecretpassword + # The first user in the list below is used for Loki/GEL authentication. + # You can add additional users if desired; they will not impact Loki/GEL. + # `accessKey` = username, `secretKey` = password + users: + - accessKey: logs-user + secretKey: supersecretpassword + policy: readwrite + buckets: + - name: chunks + policy: none + purge: false + - name: ruler + policy: none + purge: false + - name: admin + policy: none + purge: false + persistence: + size: 5Gi + annotations: {} + resources: + requests: + cpu: 100m + memory: 128Mi + # Allow the address used by Loki to refer to Minio to be overridden + address: null +# Create extra manifests via values. Would be passed through `tpl` for templating +# objects can also be provided as multiline strings, useful for templating field names +extraObjects: [] +# - apiVersion: v1 +# kind: ConfigMap +# metadata: +# name: loki-alerting-rules +# data: +# loki-alerting-rules.yaml: |- +# groups: +# - name: example +# rules: +# - alert: example +# expr: | +# sum(count_over_time({app="loki"} |~ "error")) > 0 +# for: 3m +# labels: +# severity: warning +# category: logs +# annotations: +# message: "loki has encountered errors" +# - | +# apiVersion: v1 +# kind: Secret +# type: Opaque +# metadata: +# name: loki-distributed-basic-auth +# data: +# {{- range .Values.loki.tenants }} +# {{ .name }}: {{ b64enc .password | quote }} +# {{- end }} + +sidecar: + image: + # -- The Docker registry and image for the k8s sidecar + repository: kiwigrid/k8s-sidecar + # -- Docker image tag + tag: 1.30.2 + # -- Docker image sha. If empty, no sha will be used + sha: "" + # -- Docker image pull policy + pullPolicy: IfNotPresent + # -- Resource requests and limits for the sidecar + resources: {} + # limits: + # cpu: 100m + # memory: 100Mi + # requests: + # cpu: 50m + # memory: 50Mi + # -- The SecurityContext for the sidecar. + securityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + # -- Set to true to skip tls verification for kube api calls. + skipTlsVerify: false + # -- Ensure that rule files aren't conflicting and being overwritten by prefixing their name with the namespace they are defined in. + enableUniqueFilenames: false + # -- Readiness probe definition. Probe is disabled on the sidecar by default. + readinessProbe: {} + # -- Liveness probe definition. Probe is disabled on the sidecar by default. + livenessProbe: {} + rules: + # -- Whether or not to create a sidecar to ingest rule from specific ConfigMaps and/or Secrets. + enabled: true + # -- Label that the configmaps/secrets with rules will be marked with. + label: loki_rule + # -- Label value that the configmaps/secrets with rules will be set to. + labelValue: "" + # -- Folder into which the rules will be placed. + folder: /rules + # -- Comma separated list of namespaces. If specified, the sidecar will search for config-maps/secrets inside these namespaces. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify 'ALL' to search in all namespaces. + searchNamespace: null + # -- Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH request, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # -- Search in configmap, secret, or both. + resource: both + # -- Absolute path to the shell script to execute after a configmap or secret has been reloaded. + script: null + # -- WatchServerTimeout: request to the server, asking it to cleanly close the connection after that. + # defaults to 60sec; much higher values like 3600 seconds (1h) are feasible for non-Azure K8S. + watchServerTimeout: 60 + # + # -- WatchClientTimeout: is a client-side timeout, configuring your local socket. + # If you have a network outage dropping all packets with no RST/FIN, + # this is how long your client waits before realizing & dropping the connection. + # Defaults to 66sec. + watchClientTimeout: 60 + # -- Log level of the sidecar container. + logLevel: INFO +############################################## WARNING ############################################################### +# +# DEPRECATED VALUES +# +# The following values are deprecated and will be removed in a future version of the helm chart! +# +############################################## WARNING ############################################################## + +# -- DEPRECATED Monitoring section determines which monitoring features to enable, this section is being replaced +# by https://github.com/grafana/meta-monitoring-chart +monitoring: + # Dashboards for monitoring Loki + dashboards: + # -- If enabled, create configmap with dashboards for monitoring Loki + enabled: false + # -- Alternative namespace to create dashboards ConfigMap in + namespace: null + # -- Additional annotations for the dashboards ConfigMap + annotations: {} + # -- Labels for the dashboards ConfigMap + labels: + grafana_dashboard: "1" + # -- DEPRECATED Recording rules for monitoring Loki, required for some dashboards + rules: + # -- If enabled, create PrometheusRule resource with Loki recording rules + enabled: false + # -- Include alerting rules + alerting: true + # -- Specify which individual alerts should be disabled + # -- Instead of turning off each alert one by one, set the .monitoring.rules.alerting value to false instead. + # -- If you disable all the alerts and keep .monitoring.rules.alerting set to true, the chart will fail to render. + disabled: {} + # LokiRequestErrors: true + # LokiRequestPanics: true + # -- Alternative namespace to create PrometheusRule resources in + namespace: null + # -- Additional annotations for the rules PrometheusRule resource + annotations: {} + # -- Additional labels for the rules PrometheusRule resource + labels: {} + # -- Additional labels for PrometheusRule alerts + additionalRuleLabels: {} + # -- Additional groups to add to the rules file + additionalGroups: [] + # - name: additional-loki-rules + # rules: + # - record: job:loki_request_duration_seconds_bucket:sum_rate + # expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job) + # - record: job_route:loki_request_duration_seconds_bucket:sum_rate + # expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job, route) + # - record: node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate + # expr: sum(rate(container_cpu_usage_seconds_total[1m])) by (node, namespace, pod, container) + # -- DEPRECATED ServiceMonitor configuration + serviceMonitor: + # -- If enabled, ServiceMonitor resources for Prometheus Operator are created + enabled: false + # -- Namespace selector for ServiceMonitor resources + namespaceSelector: {} + # -- ServiceMonitor annotations + annotations: {} + # -- Additional ServiceMonitor labels + labels: {} + # -- ServiceMonitor scrape interval + # Default is 15s because included recording rules use a 1m rate, and scrape interval needs to be at + # least 1/4 rate interval. + interval: 15s + # -- ServiceMonitor scrape timeout in Go duration format (e.g. 15s) + scrapeTimeout: null + # -- ServiceMonitor relabel configs to apply to samples before scraping + # https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + relabelings: [] + # -- ServiceMonitor metric relabel configs to apply to samples before ingestion + # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#endpoint + metricRelabelings: [] + # -- ServiceMonitor will use http by default, but you can pick https as well + scheme: http + # -- ServiceMonitor will use these tlsConfig settings to make the health check requests + tlsConfig: null + # -- If defined, will create a MetricsInstance for the Grafana Agent Operator. + metricsInstance: + # -- If enabled, MetricsInstance resources for Grafana Agent Operator are created + enabled: true + # -- MetricsInstance annotations + annotations: {} + # -- Additional MetricsInstance labels + labels: {} + # -- If defined a MetricsInstance will be created to remote write metrics. + remoteWrite: null + # -- DEPRECATED Self monitoring determines whether Loki should scrape its own logs. + # This feature currently relies on the Grafana Agent Operator being installed, + # which is installed by default using the grafana-agent-operator sub-chart. + # It will create custom resources for GrafanaAgent, LogsInstance, and PodLogs to configure + # scrape configs to scrape its own logs with the labels expected by the included dashboards. + selfMonitoring: + enabled: false + # -- Tenant to use for self monitoring + tenant: + # -- Name of the tenant + name: "self-monitoring" + # -- Password of the gateway for Basic auth + password: null + # -- Namespace to create additional tenant token secret in. Useful if your Grafana instance + # is in a separate namespace. Token will still be created in the canary namespace. + secretNamespace: "{{ .Release.Namespace }}" + # -- DEPRECATED Grafana Agent configuration + grafanaAgent: + # -- DEPRECATED Controls whether to install the Grafana Agent Operator and its CRDs. + # Note that helm will not install CRDs if this flag is enabled during an upgrade. + # In that case install the CRDs manually from https://github.com/grafana/agent/tree/main/production/operator/crds + installOperator: false + # -- Grafana Agent annotations + annotations: {} + # -- Additional Grafana Agent labels + labels: {} + # -- Enable the config read api on port 8080 of the agent + enableConfigReadAPI: false + # -- The name of the PriorityClass for GrafanaAgent pods + priorityClassName: null + # -- Resource requests and limits for the grafanaAgent pods + resources: {} + # limits: + # memory: 200Mi + # requests: + # cpu: 50m + # memory: 100Mi + # -- Tolerations for GrafanaAgent pods + tolerations: [] + # PodLogs configuration + podLogs: + # -- PodLogs version + apiVersion: monitoring.grafana.com/v1alpha1 + # -- PodLogs annotations + annotations: {} + # -- Additional PodLogs labels + labels: {} + # -- PodLogs relabel configs to apply to samples before scraping + # https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + relabelings: [] + # -- Additional pipeline stages to process logs after scraping + # https://grafana.com/docs/agent/latest/operator/api/#pipelinestagespec-a-namemonitoringgrafanacomv1alpha1pipelinestagespeca + additionalPipelineStages: [] + # LogsInstance configuration + logsInstance: + # -- LogsInstance annotations + annotations: {} + # -- Additional LogsInstance labels + labels: {} + # -- Additional clients for remote write + clients: null +# -- DEPRECATED Configuration for the table-manager. The table-manager is only necessary when using a deprecated +# index type such as Cassandra, Bigtable, or DynamoDB, it has not been necessary since loki introduced self- +# contained index types like 'boltdb-shipper' and 'tsdb'. This will be removed in a future helm chart. +tableManager: + # -- Specifies whether the table-manager should be enabled + enabled: false + image: + # -- The Docker registry for the table-manager image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the table-manager image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the table-manager image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for table-manager pods + priorityClassName: null + # -- Labels for table-manager pods + podLabels: {} + # -- Annotations for table-manager deployment + annotations: {} + # -- Annotations for table-manager pods + podAnnotations: {} + service: + # -- Annotations for table-manager Service + annotations: {} + # -- Additional labels for table-manager Service + labels: {} + # -- Additional CLI args for the table-manager + extraArgs: [] + # -- Environment variables to add to the table-manager pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the table-manager pods + extraEnvFrom: [] + # -- Volume mounts to add to the table-manager pods + extraVolumeMounts: [] + # -- Volumes to add to the table-manager pods + extraVolumes: [] + # -- Resource requests and limits for the table-manager + resources: {} + # -- Containers to add to the table-manager pods + extraContainers: [] + # -- Grace period to allow the table-manager to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for table-manager pods. + # @default -- Hard node and anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: table-manager + topologyKey: kubernetes.io/hostname + # -- DNS config table-manager pods + dnsConfig: {} + # -- Node selector for table-manager pods + nodeSelector: {} + # -- Tolerations for table-manager pods + tolerations: [] + # -- Enable deletes by retention + retention_deletes_enabled: false + # -- Set retention period + retention_period: 0 diff --git a/charts/lvm-localpv/Chart.lock b/charts/lvm-localpv/Chart.lock new file mode 100644 index 0000000..366f397 --- /dev/null +++ b/charts/lvm-localpv/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: crds + repository: "" + version: 1.8.0 +digest: sha256:21f9b5c7bfa148f097a5fb8ec53c5b14c94cc3cebe06fc55d5b79960b72f79cb +generated: "2025-11-18T07:25:52.778067818Z" diff --git a/charts/lvm-localpv/Chart.yaml b/charts/lvm-localpv/Chart.yaml new file mode 100644 index 0000000..91021ae --- /dev/null +++ b/charts/lvm-localpv/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +appVersion: 1.8.0 +dependencies: +- condition: crds.enabled + name: crds + repository: "" + version: 1.8.0 +description: CSI Driver for dynamic provisioning of LVM Persistent Local Volumes. +home: https://openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- filesystem +- LVM +- Local Persistent Volumes +- storage +name: lvm-localpv +sources: +- https://github.com/openebs/lvm-localpv +version: 1.8.0 diff --git a/charts/lvm-localpv/README.md b/charts/lvm-localpv/README.md new file mode 100644 index 0000000..4796e35 --- /dev/null +++ b/charts/lvm-localpv/README.md @@ -0,0 +1,153 @@ + +# OpenEBS LocalPV Provisioner + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Chart Lint and Test](https://github.com/openebs/lvm-localpv/workflows/Chart%20Lint%20and%20Test/badge.svg) +![Release Charts](https://github.com/openebs/lvm-localpv/workflows/Release%20Charts/badge.svg?branch=develop) + +A Helm chart for openebs lvm localpv provisioner. This chart bootstraps OpenEBS LVM LocalPV provisioner deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + + +**Homepage:** + +## Get Repo Info + +```console +helm repo add openebs-lvmlocalpv https://openebs.github.io/lvm-localpv +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +Please visit the [link](https://openebs.github.io/lvm-localpv/) for install instructions via helm3. + +```console +# Helm +$ helm install [RELEASE_NAME] openebs-lvmlocalpv/lvm-localpv --namespace [NAMESPACE] +``` + +
+ Click here if you're using MicroK8s. + + ```console + microk8s helm3 install [RELEASE_NAME] openebs-lvmlocalpv/lvm-localpv --namespace [NAMESPACE] --set-string lvmNode.kubeletDir="/var/snap/microk8s/common/var/lib/kubelet/" + ``` +
+ + +**Note:** If moving from the operator to helm +- Make sure the namespace provided in the helm install command is same as `OPENEBS_NAMESPACE` (by default it is `openebs`) env in the controller deployment. +- Before installing, clean up the stale deployment and daemonset from `kube-system` namespace using the below commands +```sh +kubectl delete deployment openebs-lvm-controller -n kube-system +kubectl delete ds openebs-lvm-node -n kube-system +``` + + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +# Helm +$ helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +# Helm +$ helm upgrade [RELEASE_NAME] [CHART] --install --namespace [NAMESPACE] +``` + +## Configuration + +The following table lists the configurable parameters of the OpenEBS LVM Localpv chart and their default values. + +```console +helm install openebs-lvmlocalpv openebs-lvmlocalpv/lvm-localpv --namespace openebs --create-namespace +``` +
+ Click here if you're using MicroK8s. + + If you are using MicroK8s, it is necessary to add the following flag: + + ```console + --set-string lvmNode.kubeletDir="/var/snap/microk8s/common/var/lib/kubelet/" + ``` +
+ +| Parameter | Description | Default | +|-----------------------------------------------------|----------------------------------------------------------------------------------|-----------------------------------------| +| `crds.csi.volumeSnapshots.enabled` | Enable/Disable installation of VolumeSnapshot-related CRDs | `true` | +| `imagePullSecrets` | Provides image pull secret | `""` | +| `lvmPlugin.image.registry` | Registry for openebs-lvm-plugin image | `""` | +| `lvmPlugin.image.repository` | Image repository for openebs-lvm-plugin | `openebs/lvm-driver` | +| `lvmPlugin.image.pullPolicy` | Image pull policy for openebs-lvm-plugin | `IfNotPresent` | +| `lvmPlugin.image.tag` | Image tag for openebs-lvm-plugin | `1.6.1` | +| `lvmPlugin.metricsPort` | The TCP port number used for exposing lvm-metrics | `9500` | +| `lvmPlugin.allowedTopologies` | The comma seperated list of allowed node topologies | `kubernetes.io/hostname,` | +| `lvmNode.driverRegistrar.image.registry` | Registry for csi-node-driver-registrar image | `registry.k8s.io/` | +| `lvmNode.driverRegistrar.image.repository` | Image repository for csi-node-driver-registrar | `sig-storage/csi-node-driver-registrar` | +| `lvmNode.driverRegistrar.image.pullPolicy` | Image pull policy for csi-node-driver-registrar | `IfNotPresent` | +| `lvmNode.driverRegistrar.image.tag` | Image tag for csi-node-driver-registrar | `v2.8.0` | +| `lvmNode.updateStrategy.type` | Update strategy for lvmnode daemonset | `RollingUpdate` | +| `lvmNode.kubeletDir` | Kubelet mount point for lvmnode daemonset | `"/var/lib/kubelet/"` | +| `lvmNode.annotations` | Annotations for lvmnode daemonset metadata | `""` | +| `lvmNode.podAnnotations` | Annotations for lvmnode daemonset's pods metadata | `""` | +| `lvmNode.resources` | Resource and request and limit for lvmnode daemonset containers | `""` | +| `lvmNode.labels` | Labels for lvmnode daemonset metadata | `""` | +| `lvmNode.podLabels` | Appends labels to the lvmnode daemonset pods | `""` | +| `lvmNode.nodeSelector` | Nodeselector for lvmnode daemonset pods | `""` | +| `lvmNode.tolerations` | lvmnode daemonset's pod toleration values | `""` | +| `lvmNode.securityContext` | Security context for lvmnode daemonset container | `""` | +| `lvmController.resizer.image.registry` | Registry for csi-resizer image | `registry.k8s.io/` | +| `lvmController.resizer.image.repository` | Image repository for csi-resizer | `sig-storage/csi-resizer` | +| `lvmController.resizer.image.pullPolicy` | Image pull policy for csi-resizer | `IfNotPresent` | +| `lvmController.resizer.image.tag` | Image tag for csi-resizer | `v1.8.0` | +| `lvmController.snapshotter.image.registry` | Registry for csi-snapshotter image | `registry.k8s.io/` | +| `lvmController.snapshotter.image.repository` | Image repository for csi-snapshotter | `sig-storage/csi-snapshotter` | +| `lvmController.snapshotter.image.pullPolicy` | Image pull policy for csi-snapshotter | `IfNotPresent` | +| `lvmController.snapshotter.image.tag` | Image tag for csi-snapshotter | `v6.2.2` | +| `lvmController.snapshotController.image.registry` | Registry for snapshot-controller image | `registry.k8s.io/` | +| `lvmController.snapshotController.image.repository` | Image repository for snapshot-controller | `sig-storage/snapshot-controller` | +| `lvmController.snapshotController.image.pullPolicy` | Image pull policy for snapshot-controller | `IfNotPresent` | +| `lvmController.snapshotController.image.tag` | Image tag for snapshot-controller | `v6.2.2` | +| `lvmController.provisioner.image.registry` | Registry for csi-provisioner image | `registry.k8s.io/` | +| `lvmController.provisioner.image.repository` | Image repository for csi-provisioner | `sig-storage/csi-provisioner` | +| `lvmController.provisioner.image.pullPolicy` | Image pull policy for csi-provisioner | `IfNotPresent` | +| `lvmController.provisioner.image.tag` | Image tag for csi-provisioner | `v3.5.0` | +| `lvmController.updateStrategy.type` | Update strategy for lvm localpv controller deployment | `RollingUpdate` | +| `lvmController.annotations` | Annotations for lvm localpv controller deployment metadata | `""` | +| `lvmController.podAnnotations` | Annotations for lvm localpv controller deployment's pods metadata | `""` | +| `lvmController.resources` | Resource and request and limit for lvm localpv controller deployment containers | `""` | +| `lvmController.labels` | Labels for lvm localpv controller deployment metadata | `""` | +| `lvmController.podLabels` | Appends labels to the lvm localpv controller deployment pods | `""` | +| `lvmController.nodeSelector` | Nodeselector for lvm localpv controller deployment pods | `""` | +| `lvmController.tolerations` | lvm localpv controller deployment's pod toleration values | `""` | +| `lvmController.topologySpreadConstraints` | lvm localpv controller deployment's pod topologySpreadConstraints values | `""` | +| `lvmController.securityContext` | Security context for lvm localpv controller deployment container | `""` | +| `rbac.pspEnabled` | Enable PodSecurityPolicy | `false` | +| `serviceAccount.lvmNode.create` | Create a service account for lvmnode or not | `true` | +| `serviceAccount.lvmNode.name` | Name for the lvmnode service account | `openebs-lvm-node-sa` | +| `serviceAccount.lvmController.create` | Create a service account for lvm localpv controller or not | `true` | +| `serviceAccount.lvmController.name` | Name for the lvm localpv controller service account | `openebs-lvm-controller-sa` | +| `analytics.enabled` | Enable or Disable google analytics for the controller | `true` | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml openebs/lvm-localpv +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/charts/lvm-localpv/charts/crds/.helmignore b/charts/lvm-localpv/charts/crds/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/lvm-localpv/charts/crds/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/lvm-localpv/charts/crds/Chart.yaml b/charts/lvm-localpv/charts/crds/Chart.yaml new file mode 100644 index 0000000..e9dd520 --- /dev/null +++ b/charts/lvm-localpv/charts/crds/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +description: A Helm chart that collects CustomResourceDefinitions (CRDs) from lvm-localpv. +name: crds +version: 1.8.0 diff --git a/charts/lvm-localpv/charts/crds/templates/_helpers.tpl b/charts/lvm-localpv/charts/crds/templates/_helpers.tpl new file mode 100644 index 0000000..8e6eef8 --- /dev/null +++ b/charts/lvm-localpv/charts/crds/templates/_helpers.tpl @@ -0,0 +1,18 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* + Adds extra annotations to CRDs. This targets two scenarios: preventing CRD recycling in case + the chart is removed; and adding custom annotations. + NOTE: This function assumes the element `metadata.annotations` already exists. + Usage: + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} +*/}} + +{{- define "crds.extraAnnotations" -}} +{{- if .keep -}} +helm.sh/resource-policy: keep +{{ end }} +{{- with .annotations }} + {{- toYaml . }} +{{- end }} +{{- end -}} \ No newline at end of file diff --git a/charts/lvm-localpv/charts/crds/templates/csi-volume-snapshot-class.yaml b/charts/lvm-localpv/charts/crds/templates/csi-volume-snapshot-class.yaml new file mode 100644 index 0000000..ba00aa3 --- /dev/null +++ b/charts/lvm-localpv/charts/crds/templates/csi-volume-snapshot-class.yaml @@ -0,0 +1,155 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: | + Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshotClass + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: false + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/lvm-localpv/charts/crds/templates/csi-volume-snapshot-content.yaml b/charts/lvm-localpv/charts/crds/templates/csi-volume-snapshot-content.yaml new file mode 100644 index 0000000..96c4a98 --- /dev/null +++ b/charts/lvm-localpv/charts/crds/templates/csi-volume-snapshot-content.yaml @@ -0,0 +1,499 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + oneOf: + - required: + - snapshotHandle + - required: + - volumeHandle + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + sourceVolumeMode: + description: SourceVolumeMode is the mode of the volume whose snapshot + is taken. Can be either “Filesystem” or “Block”. If not specified, + it indicates the source volume's mode is unknown. This field is + immutable. This field is an alpha field. + type: string + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: | + If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future. + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: | + Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: | + creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + volumeGroupSnapshotContentName: + description: VolumeGroupSnapshotContentName is the name of the VolumeGroupSnapshotContent + of which this VolumeSnapshotContent is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshotContent + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: | + If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future. + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: | + Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/lvm-localpv/charts/crds/templates/csi-volume-snapshot.yaml b/charts/lvm-localpv/charts/crds/templates/csi-volume-snapshot.yaml new file mode 100644 index 0000000..024eb0d --- /dev/null +++ b/charts/lvm-localpv/charts/crds/templates/csi-volume-snapshot.yaml @@ -0,0 +1,400 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + oneOf: + - required: + - persistentVolumeClaimName + - required: + - volumeSnapshotContentName + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + volumeSnapshotClassName: + description: | + VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field. + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: | + boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + x-kubernetes-int-or-string: true + volumeGroupSnapshotName: + description: VolumeGroupSnapshotName is the name of the VolumeGroupSnapshot + of which this VolumeSnapshot is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshot + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: | + spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required. + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + volumeSnapshotClassName: + description: | + VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field. + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: | + boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/lvm-localpv/charts/crds/templates/lvmnode.yaml b/charts/lvm-localpv/charts/crds/templates/lvmnode.yaml new file mode 100644 index 0000000..dda88f7 --- /dev/null +++ b/charts/lvm-localpv/charts/crds/templates/lvmnode.yaml @@ -0,0 +1,208 @@ +{{- if .Values.lvmLocalPv.enabled -}} +############################################## +########### ############ +########### LVMNode CRD ############ +########### ############ +############################################## + +# LVMNode CRD is autogenerated via `make manifests` command. +# Do the modification in the code and run the `make manifests` command +# to generate the CRD definition + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + {{- include "crds.extraAnnotations" .Values.lvmLocalPv | nindent 4 }} + creationTimestamp: null + name: lvmnodes.local.openebs.io +spec: + group: local.openebs.io + names: + kind: LVMNode + listKind: LVMNodeList + plural: lvmnodes + shortNames: + - lvmnode + singular: lvmnode + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: LVMNode records information about all lvm volume groups available + in a node. In general, the openebs node-agent creates the LVMNode object + & periodically synchronizing the volume groups available in the node. LVMNode + has an owner reference pointing to the corresponding node object. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + volumeGroups: + items: + description: VolumeGroup specifies attributes of a given vg exists on + node. + properties: + allocationPolicy: + description: 'AllocationPolicy indicates the volume group allocation + policy. AllocationPolicy has the following mapping between int + and string for its value: [-1: "", 0: "normal", 1: "contiguous", + 2: "cling", 3: "anywhere", 4: "inherited"]' + type: integer + free: + anyOf: + - type: integer + - type: string + description: Free specifies the available capacity of volume group. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + lvCount: + description: LVCount denotes total number of logical volumes in + volume group. + format: int32 + minimum: 0 + type: integer + maxLv: + description: MaxLV denotes maximum number of logical volumes allowed + in volume group or 0 if unlimited. + format: int32 + type: integer + maxPv: + description: MaxPV denotes maximum number of physical volumes allowed + in volume group or 0 if unlimited. + format: int32 + type: integer + metadataCount: + description: MetadataCount denotes number of metadata areas on the + volume group. + format: int32 + type: integer + metadataFree: + anyOf: + - type: integer + - type: string + description: MetadataFree specifies the available metadata area + space for the volume group + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + metadataSize: + anyOf: + - type: integer + - type: string + description: MetadataSize specifies size of smallest metadata area + for the volume group + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + metadataUsedCount: + description: MetadataUsedCount denotes number of used metadata areas + in volume group + format: int32 + type: integer + missingPvCount: + description: MissingPVCount denotes number of physical volumes in + volume group which are missing. + format: int32 + type: integer + name: + description: Name of the lvm volume group. + minLength: 1 + type: string + permissions: + description: 'Permission indicates the volume group permission which + can be writable or read-only. Permission has the following mapping + between int and string for its value: [-1: "", 0: "writeable", + 1: "read-only"]' + type: integer + pvCount: + description: PVCount denotes total number of physical volumes constituting + the volume group. + format: int32 + minimum: 0 + type: integer + size: + anyOf: + - type: integer + - type: string + description: Size specifies the total size of volume group. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + snapCount: + description: SnapCount denotes number of snapshots in volume group. + format: int32 + type: integer + thinPools: + description: ThinPools hosted by the volume group. + items: + description: ThinPool LV present on VG. + properties: + free: + anyOf: + - type: integer + - type: string + description: Free capacity of thinpool. In bytes, if no unit + specified. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + name: + description: Name of the thinpool lv. + type: string + size: + anyOf: + - type: integer + - type: string + description: Size of the thinpool lv. In bytes, if no unit + specified. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - free + - name + - size + type: object + type: array + uuid: + description: UUID denotes a unique identity of a lvm volume group. + minLength: 1 + type: string + required: + - allocationPolicy + - free + - lvCount + - maxLv + - maxPv + - metadataCount + - metadataFree + - metadataSize + - metadataUsedCount + - missingPvCount + - name + - permissions + - pvCount + - size + - snapCount + - uuid + type: object + type: array + required: + - volumeGroups + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} \ No newline at end of file diff --git a/charts/lvm-localpv/charts/crds/templates/lvmsnapshot.yaml b/charts/lvm-localpv/charts/crds/templates/lvmsnapshot.yaml new file mode 100644 index 0000000..f7daabc --- /dev/null +++ b/charts/lvm-localpv/charts/crds/templates/lvmsnapshot.yaml @@ -0,0 +1,98 @@ +{{- if .Values.lvmLocalPv.enabled -}} +############################################## +########### ############ +########### LVMSnapshot CRD ############ +########### ############ +############################################## + +# LVMSnapshot CRD is autogenerated via `make manifests` command. +# Do the modification in the code and run the `make manifests` command +# to generate the CRD definition + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + {{- include "crds.extraAnnotations" .Values.lvmLocalPv | nindent 4 }} + creationTimestamp: null + name: lvmsnapshots.local.openebs.io +spec: + group: local.openebs.io + names: + kind: LVMSnapshot + listKind: LVMSnapshotList + plural: lvmsnapshots + singular: lvmsnapshot + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: LVMSnapshot represents an LVM Snapshot of the lvm volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: LVMSnapshotSpec defines LVMSnapshot spec + properties: + ownerNodeID: + description: OwnerNodeID is the Node ID where the volume group is + present which is where the snapshot has been provisioned. OwnerNodeID + can not be edited after the snapshot has been provisioned. + minLength: 1 + type: string + snapSize: + description: SnapSize specifies the space reserved for the snapshot + type: string + thinProvision: + description: ThinProvision specifies whether the snapshot is thin-provisioned + or not. + type: boolean + volGroup: + description: VolGroup specifies the name of the volume group where + the snapshot has been created. + type: string + required: + - ownerNodeID + - volGroup + type: object + status: + description: SnapStatus string that reflects if the snapshot was created + successfully + properties: + lvSize: + anyOf: + - type: integer + - type: string + description: LvSize specifies the size allocated for the snapshot + in the VG + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + state: + type: string + type: object + required: + - spec + - status + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} \ No newline at end of file diff --git a/charts/lvm-localpv/charts/crds/templates/lvmvolume.yaml b/charts/lvm-localpv/charts/crds/templates/lvmvolume.yaml new file mode 100644 index 0000000..307791d --- /dev/null +++ b/charts/lvm-localpv/charts/crds/templates/lvmvolume.yaml @@ -0,0 +1,161 @@ +{{- if .Values.lvmLocalPv.enabled -}} +############################################## +########### ############ +########### LVMVolume CRD ############ +########### ############ +############################################## + +# LVMVolume CRD is autogenerated via `make manifests` command. +# Do the modification in the code and run the `make manifests` command +# to generate the CRD definition + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + {{- include "crds.extraAnnotations" .Values.lvmLocalPv | nindent 4 }} + creationTimestamp: null + name: lvmvolumes.local.openebs.io +spec: + group: local.openebs.io + names: + kind: LVMVolume + listKind: LVMVolumeList + plural: lvmvolumes + shortNames: + - lvmvol + singular: lvmvolume + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: volume group where the volume is created + jsonPath: .spec.volGroup + name: VolGroup + type: string + - description: Node where the volume is created + jsonPath: .spec.ownerNodeID + name: Node + type: string + - description: Size of the volume + jsonPath: .spec.capacity + name: Size + type: string + - description: Status of the volume + jsonPath: .status.state + name: Status + type: string + - description: Age of the volume + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: LVMVolume represents a LVM based volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: VolumeInfo defines LVM info + properties: + capacity: + description: Capacity of the volume + minLength: 1 + type: string + ownerNodeID: + description: OwnerNodeID is the Node ID where the volume group is + present which is where the volume has been provisioned. OwnerNodeID + can not be edited after the volume has been provisioned. + minLength: 1 + type: string + shared: + description: Shared specifies whether the volume can be shared among + multiple pods. If it is not set to "yes", then the LVM LocalPV Driver + will not allow the volumes to be mounted by more than one pods. + enum: + - "yes" + - "no" + type: string + source: + description: |- + Source defines the data source from which the volume should be created. + It can reference either a snapshot or an existing volume. + If not specified, a standard LVM volume will be created. + If specified, the new volume will be created using the defined data source. + type: string + thinProvision: + description: ThinProvision specifies whether logical volumes can be + thinly provisioned. If it is set to "yes", then the LVM LocalPV + Driver will create thinProvision i.e. logical volumes that are larger + than the available extents. + enum: + - "yes" + - "no" + type: string + vgPattern: + description: VgPattern specifies the regex to choose volume groups + where volume needs to be created. + type: string + volGroup: + description: VolGroup specifies the name of the volume group where + the volume has been created. + type: string + required: + - capacity + - ownerNodeID + - vgPattern + - volGroup + type: object + status: + description: VolStatus string that specifies the current state of the + volume provisioning request. + properties: + error: + description: Error denotes the error occurred during provisioning/expanding + a volume. Error field should only be set when State becomes Failed. + properties: + code: + description: VolumeErrorCode represents the error code to represent + specific class of errors. + type: string + message: + type: string + type: object + state: + description: State specifies the current state of the volume provisioning + request. The state "Pending" means that the volume creation request + has not processed yet. The state "Ready" means that the volume has + been created and it is ready for the use. "Failed" means that volume + provisioning has been failed and will not be retried by node agent + controller. + enum: + - Pending + - Ready + - Failed + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} \ No newline at end of file diff --git a/charts/lvm-localpv/charts/crds/values.yaml b/charts/lvm-localpv/charts/crds/values.yaml new file mode 100644 index 0000000..a7ef0f5 --- /dev/null +++ b/charts/lvm-localpv/charts/crds/values.yaml @@ -0,0 +1,12 @@ +lvmLocalPv: + # Install lvm-localpv CRDs + enabled: true + # Keep CRDs on chart uninstall + keep: true + +csi: + volumeSnapshots: + # Install Volume Snapshot CRDs + enabled: true + # Keep CRDs on chart uninstall + keep: true diff --git a/charts/lvm-localpv/templates/NOTES.txt b/charts/lvm-localpv/templates/NOTES.txt new file mode 100644 index 0000000..cc5aaf6 --- /dev/null +++ b/charts/lvm-localpv/templates/NOTES.txt @@ -0,0 +1,5 @@ +The OpenEBS LVM LocalPV has been installed. Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} -l role=openebs-lvm + +For more information, visit our Slack at https://openebs.io/community or view +the documentation online at http://docs.openebs.io/. diff --git a/charts/lvm-localpv/templates/_helpers.tpl b/charts/lvm-localpv/templates/_helpers.tpl new file mode 100644 index 0000000..34580e9 --- /dev/null +++ b/charts/lvm-localpv/templates/_helpers.tpl @@ -0,0 +1,145 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "lvmlocalpv.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified localpv provisioner 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 "lvmlocalpv.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "lvmlocalpv.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Create the name of the service account for controller +*/}} +{{- define "lvmlocalpv.lvmController.serviceAccountName" -}} +{{- if .Values.serviceAccount.lvmController.create }} +{{- default (include "lvmlocalpv.fullname" .) .Values.serviceAccount.lvmController.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.lvmController.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "lvmlocalpv.lvmNode.serviceAccountName" -}} +{{- if .Values.serviceAccount.lvmNode.create }} +{{- default (include "lvmlocalpv.fullname" .) .Values.serviceAccount.lvmNode.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.lvmNode.name }} +{{- end -}} +{{- end -}} + +{{/* +Define meta labels for openebs lvm-localpv components +*/}} +{{- define "lvmlocalpv.common.metaLabels" -}} +chart: {{ template "lvmlocalpv.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Chart.AppVersion | quote }} +role: {{ .Values.role | quote }} +{{- end -}} + +{{/* +Create match labels for openebs lvm-localpv controller +*/}} +{{- define "lvmlocalpv.lvmController.matchLabels" -}} +app: {{ .Values.lvmController.componentName | quote }} +release: {{ .Release.Name }} +component: {{ .Values.lvmController.componentName | quote }} +{{- end -}} + +{{/* +Create component labels for lvmlocalpv controller +*/}} +{{- define "lvmlocalpv.lvmController.componentLabels" -}} +openebs.io/component-name: {{ .Values.lvmController.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for openebs lvm-localpv controller +*/}} +{{- define "lvmlocalpv.lvmController.labels" -}} +{{ include "lvmlocalpv.common.metaLabels" . }} +{{ include "lvmlocalpv.lvmController.matchLabels" . }} +{{ include "lvmlocalpv.lvmController.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for openebs lvm-localpv node daemon +*/}} +{{- define "lvmlocalpv.lvmNode.matchLabels" -}} +name: {{ .Values.lvmNode.componentName | quote }} +release: {{ .Release.Name }} +{{- end -}} + +{{/* +Create component labels openebs lvm-localpv node daemon +*/}} +{{- define "lvmlocalpv.lvmNode.componentLabels" -}} +openebs.io/component-name: {{ .Values.lvmNode.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for openebs lvm-localpv node daemon +*/}} +{{- define "lvmlocalpv.lvmNode.labels" -}} +{{ include "lvmlocalpv.common.metaLabels" . }} +{{ include "lvmlocalpv.lvmNode.matchLabels" . }} +{{ include "lvmlocalpv.lvmNode.componentLabels" . }} +{{- end -}} + +{{/* +Create the name of the priority class for csi node plugin +*/}} +{{- define "lvmlocalpv.lvmNode.priorityClassName" -}} +{{- if .Values.lvmNode.priorityClass.create }} +{{- printf "%s-%s" .Release.Name .Values.lvmNode.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Values.lvmNode.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Create the name of the priority class for csi controller plugin +*/}} +{{- define "lvmlocalpv.lvmController.priorityClassName" -}} +{{- if .Values.lvmController.priorityClass.create }} +{{- printf "%s-%s" .Release.Name .Values.lvmController.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Values.lvmController.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Ensure that the path to kubelet ends with a slash +*/}} +{{- define "lvmlocalpv.lvmNode.kubeletDir" -}} +{{- printf "%s/" (.Values.lvmNode.kubeletDir | trimSuffix "/") -}} +{{- end }} diff --git a/charts/lvm-localpv/templates/csidriver.yaml b/charts/lvm-localpv/templates/csidriver.yaml new file mode 100644 index 0000000..5eeac54 --- /dev/null +++ b/charts/lvm-localpv/templates/csidriver.yaml @@ -0,0 +1,10 @@ +# Create the CSI Driver object +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: local.csi.openebs.io +spec: + # do not require volumeattachment + attachRequired: false + podInfoOnMount: true + storageCapacity: {{ .Values.storageCapacity }} diff --git a/charts/lvm-localpv/templates/lvm-controller.yaml b/charts/lvm-localpv/templates/lvm-controller.yaml new file mode 100644 index 0000000..03bc618 --- /dev/null +++ b/charts/lvm-localpv/templates/lvm-controller.yaml @@ -0,0 +1,163 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "lvmlocalpv.fullname" . }}-controller + {{- with .Values.lvmController.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "lvmlocalpv.lvmController.matchLabels" . | nindent 6 }} + replicas: {{ .Values.lvmController.replicas }} + template: + metadata: + {{- with .Values.lvmController.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 8 }} + {{- with .Values.lvmController.podLabels}} + {{ toYaml . | nindent 8 }} + {{- end}} + {{- with .Values.loggingLabels}} + {{ toYaml . | nindent 8 }} + {{- end}} + spec: +{{- if .Values.lvmController.priorityClass.create }} + priorityClassName: {{ template "lvmlocalpv.lvmController.priorityClassName" . }} +{{- end }} + serviceAccountName: {{ .Values.serviceAccount.lvmController.name }} + containers: + - name: {{ .Values.lvmController.resizer.name }} + image: "{{ .Values.lvmController.resizer.image.registry }}{{ .Values.lvmController.resizer.image.repository }}:{{ .Values.lvmController.resizer.image.tag }}" + args: + - "--v={{ .Values.lvmController.logLevel }}" + - "--csi-address=$(ADDRESS)" + {{- if gt (int .Values.lvmController.replicas) 1 }} + - "--leader-election" + {{- end }} + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.lvmController.resizer.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: + {{- toYaml .Values.lvmController.resources | nindent 12 }} + - name: {{ .Values.lvmController.snapshotter.name }} + image: "{{ .Values.lvmController.snapshotter.image.registry }}{{ .Values.lvmController.snapshotter.image.repository }}:{{ .Values.lvmController.snapshotter.image.tag }}" + imagePullPolicy: {{ .Values.lvmController.snapshotter.image.pullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + {{- if gt (int .Values.lvmController.replicas) 1 }} + - "--leader-election" + {{- end }} + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: + {{- toYaml .Values.lvmController.resources | nindent 12 }} + - name: {{ .Values.lvmController.snapshotController.name }} + image: "{{ .Values.lvmController.snapshotController.image.registry }}{{ .Values.lvmController.snapshotController.image.repository }}:{{ .Values.lvmController.snapshotController.image.tag }}" + args: + - "--v={{ .Values.lvmController.logLevel }}" + {{- if gt (int .Values.lvmController.replicas) 1 }} + - "--leader-election=true" + {{- end }} + imagePullPolicy: {{ .Values.lvmController.snapshotController.image.pullPolicy }} + resources: + {{- toYaml .Values.lvmController.resources | nindent 12 }} + - name: {{ .Values.lvmController.provisioner.name }} + image: "{{ .Values.lvmController.provisioner.image.registry }}{{ .Values.lvmController.provisioner.image.repository }}:{{ .Values.lvmController.provisioner.image.tag }}" + imagePullPolicy: {{ .Values.lvmController.provisioner.image.pullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + - "--v={{ .Values.lvmController.logLevel }}" + - "--feature-gates=Topology=true" + - "--strict-topology" + {{- if gt (int .Values.lvmController.replicas) 1 }} + - "--leader-election" + {{- end }} + - "--enable-capacity={{ .Values.storageCapacity }}" + - "--extra-create-metadata=true" + - "--default-fstype=ext4" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: + {{- toYaml .Values.lvmController.resources | nindent 12 }} + - name: {{ .Values.lvmPlugin.name }} + image: "{{ .Values.lvmPlugin.image.registry }}{{ .Values.lvmPlugin.image.repository }}:{{ .Values.lvmPlugin.image.tag }}" + imagePullPolicy: {{ .Values.lvmPlugin.image.pullPolicy }} + env: + - name: OPENEBS_CONTROLLER_DRIVER + value: controller + - name: OPENEBS_CSI_ENDPOINT + value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: OPENEBS_IO_INSTALLER_TYPE + value: "lvm-localpv-helm" + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + {{- if .Values.analytics.gaId }} + - name: GA_ID + value: {{ .Values.analytics.gaId | quote }} + {{- end }} + {{- if .Values.analytics.gaKey }} + - name: GA_KEY + value: {{ .Values.analytics.gaKey | quote }} + {{- end }} + args : + - "--endpoint=$(OPENEBS_CSI_ENDPOINT)" + - "--plugin=$(OPENEBS_CONTROLLER_DRIVER)" + - "--kube-api-qps={{ .Values.lvmController.kubeClientRateLimiter.qps }}" + - "--kube-api-burst={{ .Values.lvmController.kubeClientRateLimiter.burst }}" + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: + {{- toYaml .Values.lvmController.resources | nindent 12 }} + volumes: + - name: socket-dir + emptyDir: {} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.lvmController.nodeSelector }} + nodeSelector: +{{ toYaml .Values.lvmController.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.lvmController.securityContext }} + securityContext: +{{ toYaml .Values.lvmController.securityContext | indent 8 }} +{{- end }} +{{- if .Values.lvmController.tolerations }} + tolerations: +{{ toYaml .Values.lvmController.tolerations | indent 8 }} +{{- end }} +{{- if .Values.lvmController.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml .Values.lvmController.topologySpreadConstraints | indent 8 }} +{{- end }} diff --git a/charts/lvm-localpv/templates/lvm-node-service.yaml b/charts/lvm-localpv/templates/lvm-node-service.yaml new file mode 100644 index 0000000..314607a --- /dev/null +++ b/charts/lvm-localpv/templates/lvm-node-service.yaml @@ -0,0 +1,18 @@ +{{- if .Values.lvmPlugin.metricsPort }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "lvmlocalpv.fullname" . }}-node-service + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.lvmPlugin.metricsPort }} + targetPort: {{ .Values.lvmPlugin.metricsPort }} + selector: + {{- with .Values.lvmNode.podLabels }} + {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/lvm-localpv/templates/lvm-node-servicemonitor.yaml b/charts/lvm-localpv/templates/lvm-node-servicemonitor.yaml new file mode 100644 index 0000000..08f7dbe --- /dev/null +++ b/charts/lvm-localpv/templates/lvm-node-servicemonitor.yaml @@ -0,0 +1,23 @@ +{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) .Values.lvmNode.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "lvmlocalpv.fullname" . }}-node-servicemonitor + namespace: {{- .Release.Namespace }} + labels: + #release: prometheus # Adjust to match your Prometheus Operator's release name + {{- .Values.lvmNode.serviceMonitor.labels | toYaml | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 6 }} + namespaceSelector: + matchNames: + - {{- .Release.Namespace }} + endpoints: + - port: metrics + path: /metrics + interval: 30s + scrapeTimeout: 10s +{{- end }} + diff --git a/charts/lvm-localpv/templates/lvm-node.yaml b/charts/lvm-localpv/templates/lvm-node.yaml new file mode 100644 index 0000000..662b2a5 --- /dev/null +++ b/charts/lvm-localpv/templates/lvm-node.yaml @@ -0,0 +1,161 @@ +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ template "lvmlocalpv.fullname" . }}-node + {{- with .Values.lvmNode.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "lvmlocalpv.lvmNode.matchLabels" . | nindent 6 }} + updateStrategy: + rollingUpdate: + maxUnavailable: 100% + type: RollingUpdate + template: + metadata: + {{- with .Values.lvmNode.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 8 }} + {{- with .Values.lvmNode.podLabels}} + {{ toYaml . | nindent 8 }} + {{- end}} + {{- with .Values.loggingLabels}} + {{ toYaml . | nindent 8 }} + {{- end}} + spec: +{{- if .Values.lvmNode.priorityClass.create }} + priorityClassName: {{ template "lvmlocalpv.lvmNode.priorityClassName" . }} +{{- end }} + serviceAccountName: {{ .Values.serviceAccount.lvmNode.name }} + hostNetwork: {{ .Values.lvmNode.hostNetwork }} + containers: + - name: {{ .Values.lvmNode.driverRegistrar.name }} + image: "{{ .Values.lvmNode.driverRegistrar.image.registry }}{{ .Values.lvmNode.driverRegistrar.image.repository }}:{{ .Values.lvmNode.driverRegistrar.image.tag }}" + imagePullPolicy: {{ .Values.lvmNode.driverRegistrar.image.pullPolicy }} + args: + - "--v={{ .Values.lvmNode.logLevel }}" + - "--csi-address=$(ADDRESS)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "rm -rf /registration/lvm-localpv /registration/lvm-localpv-reg.sock"] + env: + - name: ADDRESS + value: /plugin/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: {{ printf "%s%s" (include "lvmlocalpv.lvmNode.kubeletDir" .) "plugins/lvm-localpv/csi.sock" | quote }} + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: NODE_DRIVER + value: openebs-lvm + volumeMounts: + - name: plugin-dir + mountPath: /plugin + - name: registration-dir + mountPath: /registration + resources: + {{- toYaml .Values.lvmNode.resources | nindent 12 }} + - name: {{ .Values.lvmPlugin.name }} + securityContext: + privileged: true + allowPrivilegeEscalation: true + image: "{{ .Values.lvmPlugin.image.registry }}{{ .Values.lvmPlugin.image.repository }}:{{ .Values.lvmPlugin.image.tag }}" + imagePullPolicy: {{ .Values.lvmPlugin.image.pullPolicy }} + args: + - "--nodeid=$(OPENEBS_NODE_ID)" + - "--endpoint=$(OPENEBS_CSI_ENDPOINT)" + - "--plugin=$(OPENEBS_NODE_DRIVER)" + - "--kube-api-qps={{ .Values.lvmNode.kubeClientRateLimiter.qps }}" + - "--kube-api-burst={{ .Values.lvmNode.kubeClientRateLimiter.burst }}" + {{- if .Values.lvmPlugin.ioLimits.enabled }} + - "--setiolimits" + - "--container-runtime=$(CONTAINER_RUNTIME)" + - "--riops-per-gb=$(RIOPS_PER_GB)" + - "--wiops-per-gb=$(WIOPS_PER_GB)" + {{- end }} + {{- if .Values.lvmPlugin.metricsPort }} + - "--listen-address=$(METRICS_LISTEN_ADDRESS)" + {{- end }} + env: + - name: OPENEBS_NODE_ID + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OPENEBS_CSI_ENDPOINT + value: unix:///plugin/csi.sock + - name: OPENEBS_NODE_DRIVER + value: agent + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.lvmPlugin.ioLimits.enabled }} + - name: CONTAINER_RUNTIME + value: {{ .Values.lvmPlugin.ioLimits.containerRuntime }} + - name: RIOPS_PER_GB + value: {{ .Values.lvmPlugin.ioLimits.readIopsPerGB }} + - name: WIOPS_PER_GB + value: {{ .Values.lvmPlugin.ioLimits.writeIopsPerGB }} + {{- end }} + {{- if .Values.lvmPlugin.metricsPort }} + - name: METRICS_LISTEN_ADDRESS + value: :{{ .Values.lvmPlugin.metricsPort }} + {{- end }} + {{- if .Values.lvmPlugin.allowedTopologies }} + - name: ALLOWED_TOPOLOGIES + value: {{ .Values.lvmPlugin.allowedTopologies }} + {{- end }} + volumeMounts: + - name: plugin-dir + mountPath: /plugin + - name: device-dir + mountPath: /dev + - name: pods-mount-dir + mountPath: {{ include "lvmlocalpv.lvmNode.kubeletDir" . | quote }} + # needed so that any mounts setup inside this container are + # propagated back to the host machine. + mountPropagation: "Bidirectional" + resources: + {{- toYaml .Values.lvmNode.resources | nindent 12 }} + volumes: + - name: device-dir + hostPath: + path: /dev + type: Directory + - name: registration-dir + hostPath: + path: {{ printf "%s%s" (include "lvmlocalpv.lvmNode.kubeletDir" .) "plugins_registry/" | quote }} + type: DirectoryOrCreate + - name: plugin-dir + hostPath: + path: {{ printf "%s%s" (include "lvmlocalpv.lvmNode.kubeletDir" .) "plugins/lvm-localpv/" | quote }} + type: DirectoryOrCreate + - name: pods-mount-dir + hostPath: + path: {{ include "lvmlocalpv.lvmNode.kubeletDir" . | quote }} + type: Directory +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.lvmNode.nodeSelector }} + nodeSelector: +{{ toYaml .Values.lvmNode.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.lvmNode.securityContext }} + securityContext: +{{ toYaml .Values.lvmNode.securityContext | indent 8 }} +{{- end }} +{{- if .Values.lvmNode.tolerations }} + tolerations: +{{ toYaml .Values.lvmNode.tolerations | indent 8 }} +{{- end }} diff --git a/charts/lvm-localpv/templates/priority-class.yaml b/charts/lvm-localpv/templates/priority-class.yaml new file mode 100644 index 0000000..44552ab --- /dev/null +++ b/charts/lvm-localpv/templates/priority-class.yaml @@ -0,0 +1,19 @@ +{{- if .Values.lvmController.priorityClass.create }} +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ template "lvmlocalpv.lvmController.priorityClassName" . }} +value: 900000000 +globalDefault: false +description: "This priority class should be used for the CStor CSI driver controller deployment only." +{{- end }} +--- +{{- if .Values.lvmNode.priorityClass.create }} +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ template "lvmlocalpv.lvmNode.priorityClassName" . }} +value: 900001000 +globalDefault: false +description: "This priority class should be used for the CStor CSI driver node deployment only." +{{- end }} diff --git a/charts/lvm-localpv/templates/psp.yaml b/charts/lvm-localpv/templates/psp.yaml new file mode 100644 index 0000000..fbe2c59 --- /dev/null +++ b/charts/lvm-localpv/templates/psp.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: openebs-lvm-node-psp + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +spec: + privileged: true + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: {{ .Values.lvmNode.hostNetwork}} + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/charts/lvm-localpv/templates/rbac.yaml b/charts/lvm-localpv/templates/rbac.yaml new file mode 100644 index 0000000..edf3a34 --- /dev/null +++ b/charts/lvm-localpv/templates/rbac.yaml @@ -0,0 +1,195 @@ +{{- if .Values.serviceAccount.lvmController.create -}} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ .Values.serviceAccount.lvmController.name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 4 }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-provisioner-role + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumes", "services"] + verbs: ["get", "list", "watch", "create", "delete", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses", "csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [ "storage.k8s.io" ] + resources: [ "csistoragecapacities"] + verbs: ["*"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["local.openebs.io"] + resources: ["lvmvolumes", "lvmsnapshots", "lvmnodes"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-provisioner-binding + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.lvmController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-lvm-provisioner-role + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-snapshotter-role + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "list", "watch", "delete"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-snapshotter-binding + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.lvmController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-lvm-snapshotter-role + apiGroup: rbac.authorization.k8s.io +--- +{{- end }} + +{{- if .Values.serviceAccount.lvmNode.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.lvmNode.name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-driver-registrar-role + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumes", "nodes", "services"] + verbs: ["get", "list"] + - apiGroups: ["local.openebs.io"] + resources: ["lvmvolumes", "lvmsnapshots", "lvmnodes"] + verbs: ["get", "list", "watch", "create", "update", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-driver-registrar-binding + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.lvmNode.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-lvm-driver-registrar-role + apiGroup: rbac.authorization.k8s.io + +{{- if .Values.rbac.pspEnabled }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-node-role + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - openebs-lvm-node-psp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: openebs-lvm-node-binding + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openebs-lvm-node-role +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.lvmNode.name }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/charts/lvm-localpv/values.yaml b/charts/lvm-localpv/values.yaml new file mode 100644 index 0000000..e2f74dd --- /dev/null +++ b/charts/lvm-localpv/values.yaml @@ -0,0 +1,202 @@ +# Default values for openebs-lvmlocalpv. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +imagePullSecrets: +# - name: "image-pull-secret" + +# enable storage capacity tracking feature +# Ref: https://kubernetes:io/docs/concepts/storage/storage-capacity +storageCapacity: true + +rbac: + # rbac.pspEnabled: `true` if PodSecurityPolicy resources should be created + pspEnabled: false + +loggingLabels: + openebs.io/logging: "true" + +# lvmNode contains the configurables for +# the lvm node daemonset +lvmNode: + componentName: openebs-lvm-node + driverRegistrar: + name: "csi-node-driver-registrar" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-node-driver-registrar + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v2.13.0 + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + # This can be configured to run on various different k8s distributions like + # microk8s where kubelet dir is different + kubeletDir: "/var/lib/kubelet/" + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + ## Labels to be added to openebs-lvm node pods + podLabels: + app: openebs-lvm-node + nodeSelector: {} + tolerations: [] + securityContext: {} + labels: {} + priorityClass: + create: true + name: lvm-localpv-csi-node-critical + logLevel: 5 + # Configure kubernetes client API requests rate. + kubeClientRateLimiter: + # Configure the number of queries per second. + qps: 0 + # Configure the maximum number of queries allowed after + # accounting for rolled over qps from previous seconds. + burst: 0 + # Disable or enable the use of hostNetwork for the lvm node daemonset. + hostNetwork: false + serviceMonitor: + enabled: false + # add labels to the serviceMonitor if you make use of serviceMonitorSelector in prometheus operator +# labels: +# release: prometheus + +# lvmController contains the configurables for +# the lvm controller deployment +lvmController: + componentName: openebs-lvm-controller + replicas: 1 + logLevel: 5 + resizer: + name: "csi-resizer" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-resizer + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v1.11.2 + snapshotter: + name: "csi-snapshotter" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-snapshotter + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v7.0.0 + snapshotController: + name: "snapshot-controller" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/snapshot-controller + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v7.0.0 + provisioner: + name: "csi-provisioner" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-provisioner + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v5.2.0 + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + ## Labels to be added to openebs-lvm controller pods + podLabels: + name: openebs-lvm-controller + nodeSelector: {} + tolerations: [] + topologySpreadConstraints: [] + securityContext: {} + priorityClass: + create: true + name: lvm-localpv-csi-controller-critical + # Configure kubernetes client API requests rate. + kubeClientRateLimiter: + # Configure the number of queries per second. + qps: 0 + # Configure the maximum number of queries allowed after + # accounting for rolled over qps from previous seconds. + burst: 0 + +# lvmPlugin is the common csi container used by the +# controller deployment and node daemonset +lvmPlugin: + name: "openebs-lvm-plugin" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: docker.io/ + repository: openebs/lvm-driver + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 1.8.0 + ioLimits: + enabled: false + containerRuntime: containerd + readIopsPerGB: "" + writeIopsPerGB: "" + # The TCP port number used for exposing lvm-metrics. + # If not set, service will not be created to expose metrics endpoint + # to serviceMonitor andlisten-address flag will not be set. + metricsPort: 9500 + # Comma seperated list of k8s worker node topologies + allowedTopologies: "kubernetes.io/hostname," + +role: openebs-lvm + +serviceAccount: + lvmController: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-lvm-controller-sa + lvmNode: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-lvm-node-sa + +analytics: + enabled: true + +crds: + lvmLocalPv: + # Install lvm-localpv CRDs + enabled: true + # Keep CRDs on chart uninstall + keep: true + csi: + volumeSnapshots: + # Install Volume Snapshot CRDs + enabled: true + # Keep CRDs on chart uninstall + keep: true diff --git a/charts/mayastor/.helmignore b/charts/mayastor/.helmignore new file mode 100644 index 0000000..39fed2c --- /dev/null +++ b/charts/mayastor/.helmignore @@ -0,0 +1,29 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +README.md.tmpl +# Nix Shell +*.nix +kubectl-plugin/ +# Chart Metadata +images.txt diff --git a/charts/mayastor/Chart.lock b/charts/mayastor/Chart.lock new file mode 100644 index 0000000..099b6bc --- /dev/null +++ b/charts/mayastor/Chart.lock @@ -0,0 +1,24 @@ +dependencies: +- name: crds + repository: "" + version: 2.10.0 +- name: etcd + repository: https://charts.bitnami.com/bitnami + version: 12.0.14 +- name: jaeger-operator + repository: https://jaegertracing.github.io/helm-charts + version: 2.50.1 +- name: loki + repository: https://grafana.github.io/helm-charts + version: 6.29.0 +- name: alloy + repository: https://grafana.github.io/helm-charts + version: 1.0.1 +- name: nats + repository: https://nats-io.github.io/k8s/helm/charts/ + version: 0.19.14 +- name: localpv-provisioner + repository: https://openebs.github.io/dynamic-localpv-provisioner + version: 4.4.0 +digest: sha256:3f8b564dcddd40fc908991e99b222abb4322d55f4d285a105cae6c9ae0c8b006 +generated: "2025-11-19T16:41:00.052587499Z" diff --git a/charts/mayastor/Chart.yaml b/charts/mayastor/Chart.yaml new file mode 100644 index 0000000..05753b3 --- /dev/null +++ b/charts/mayastor/Chart.yaml @@ -0,0 +1,103 @@ +annotations: + helm.sh/images: | + - name: alloy + image: docker.io/grafana/alloy:v1.8.1 + - name: loki + image: docker.io/grafana/loki:3.4.2 + - name: k8s-sidecar + image: docker.io/kiwigrid/k8s-sidecar:1.30.2 + - name: nats + image: docker.io/nats:2.9.17-alpine + - name: nats-box + image: docker.io/natsio/nats-box:0.13.8 + - name: nats-server-config-reloader + image: docker.io/natsio/nats-server-config-reloader:0.10.1 + - name: prometheus-nats-exporter + image: docker.io/natsio/prometheus-nats-exporter:0.11.0 + - name: alpine-bash + image: docker.io/openebs/alpine-bash:4.3.0 + - name: alpine-sh + image: docker.io/openebs/alpine-sh:4.3.0 + - name: etcd + image: docker.io/openebs/etcd:3.6.4-debian-12-r0 + - name: kubectl + image: docker.io/openebs/kubectl:1.25.15 + - name: linux-utils + image: docker.io/openebs/linux-utils:4.3.0 + - name: mayastor-agent-core + image: docker.io/openebs/mayastor-agent-core:v2.10.0 + - name: mayastor-agent-ha-cluster + image: docker.io/openebs/mayastor-agent-ha-cluster:v2.10.0 + - name: mayastor-agent-ha-node + image: docker.io/openebs/mayastor-agent-ha-node:v2.10.0 + - name: mayastor-api-rest + image: docker.io/openebs/mayastor-api-rest:v2.10.0 + - name: mayastor-csi-controller + image: docker.io/openebs/mayastor-csi-controller:v2.10.0 + - name: mayastor-csi-node + image: docker.io/openebs/mayastor-csi-node:v2.10.0 + - name: mayastor-io-engine + image: docker.io/openebs/mayastor-io-engine:v2.10.0 + - name: mayastor-metrics-exporter-io-engine + image: docker.io/openebs/mayastor-metrics-exporter-io-engine:v2.10.0 + - name: mayastor-obs-callhome-stats + image: docker.io/openebs/mayastor-obs-callhome-stats:v2.10.0 + - name: mayastor-obs-callhome + image: docker.io/openebs/mayastor-obs-callhome:v2.10.0 + - name: mayastor-operator-diskpool + image: docker.io/openebs/mayastor-operator-diskpool:v2.10.0 + - name: provisioner-localpv + image: docker.io/openebs/provisioner-localpv:4.4.0 + - name: mc + image: quay.io/minio/mc:RELEASE.2024-11-21T17-21-54Z + - name: minio + image: quay.io/minio/minio:RELEASE.2024-12-18T13-15-44Z + - name: prometheus-config-reloader + image: quay.io/prometheus-operator/prometheus-config-reloader:v0.81.0 + - name: csi-attacher + image: registry.k8s.io/sig-storage/csi-attacher:v4.8.1 + - name: csi-node-driver-registrar + image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.13.0 + - name: csi-provisioner + image: registry.k8s.io/sig-storage/csi-provisioner:v5.2.0 + - name: csi-resizer + image: registry.k8s.io/sig-storage/csi-resizer:v1.13.2 + - name: csi-snapshotter + image: registry.k8s.io/sig-storage/csi-snapshotter:v8.2.0 + - name: snapshot-controller + image: registry.k8s.io/sig-storage/snapshot-controller:v8.2.0 +apiVersion: v2 +appVersion: 2.10.0 +dependencies: +- condition: crds.enabled + name: crds + repository: "" + version: 2.10.0 +- condition: etcd.enabled + name: etcd + repository: https://charts.bitnami.com/bitnami + version: 12.0.14 +- condition: base.jaeger.enabled + name: jaeger-operator + repository: https://jaegertracing.github.io/helm-charts + version: 2.50.1 +- condition: loki.enabled + name: loki + repository: https://grafana.github.io/helm-charts + version: 6.29.0 +- condition: alloy.enabled + name: alloy + repository: https://grafana.github.io/helm-charts + version: 1.0.1 +- condition: eventing.enabled + name: nats + repository: https://nats-io.github.io/k8s/helm/charts/ + version: 0.19.14 +- condition: localpv-provisioner.enabled + name: localpv-provisioner + repository: https://openebs.github.io/dynamic-localpv-provisioner + version: 4.4.0 +description: Mayastor Helm chart for Kubernetes +name: mayastor +type: application +version: 2.10.0 diff --git a/charts/mayastor/README.md b/charts/mayastor/README.md new file mode 100644 index 0000000..2c16c71 --- /dev/null +++ b/charts/mayastor/README.md @@ -0,0 +1,246 @@ +# mayastor + +Mayastor Helm chart for Kubernetes + +![Version: 2.10.0](https://img.shields.io/badge/Version-2.10.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.10.0](https://img.shields.io/badge/AppVersion-2.10.0-informational?style=flat-square) + +## Installation Guide + +### Prerequisites + + - Make sure the [system requirement pre-requisites](https://mayastor.gitbook.io/introduction/quickstart/prerequisites) are met. + - Label the storage nodes same as the mayastor.nodeSelector in values.yaml + - Create the namespace you want the chart to be installed, or pass the `--create-namespace` flag in the `helm install` command. + ```sh + kubectl create ns + ``` + - Create secret if downloading the container images from a private repo. + ```sh + kubectl create secret docker-registry --docker-server="https://index.docker.io/v1/" --docker-username="" --docker-password="" --docker-email="" -n + ``` + +### Installing the chart via the git repo + +Clone the mayastor charts repo. +Sync the chart dependencies +```console +$ helm dependency update +``` +Install the mayastor chart using the command. +```console +$ helm install mayastor . -n +``` + +### Installing the Chart via Helm Registry + +To install the chart with the release name `mymayastor`: + +```console +$ helm repo add mayastor https://openebs.github.io/mayastor-extensions/ +$ helm install mymayastor mayastor/mayastor +``` + +### Uninstall Helm Chart + +```console +$ helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +*See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation.* + +## Chart Dependencies + +| Repository | Name | Version | +|------------|------|---------| +| | crds | 2.10.0 | +| https://charts.bitnami.com/bitnami | etcd | 12.0.14 | +| https://grafana.github.io/helm-charts | alloy | 1.0.1 | +| https://grafana.github.io/helm-charts | loki | 6.29.0 | +| https://jaegertracing.github.io/helm-charts | jaeger-operator | 2.50.1 | +| https://nats-io.github.io/k8s/helm/charts/ | nats | 0.19.14 | +| https://openebs.github.io/dynamic-localpv-provisioner | localpv-provisioner | 4.4.0 | + +## Values + +| Key | Description | Default | +|:----|:------------|:--------| +| agents.​core.​allowNonPersistentDevlink | Allow using non-persistent kernel devpaths for pool disks. Enabling this will let users to use the kernel devpaths e.g /dev/sda, for diskpools. However, this comes with associated risks if the devpaths get swapped among disks, resulting in total data loss especially if encryption is being used. | `false` | +| agents.​core.​capacity.​thin.​poolCommitment | The allowed pool commitment limit when dealing with thin provisioned volumes. Example: If the commitment is 250 and the pool is 10GiB we can overcommit the pool up to 25GiB (create 2 10GiB and 1 5GiB volume) but no further. | `"250%"` | +| agents.​core.​capacity.​thin.​snapshotCommitment | When creating snapshots for an existing volume, each replica pool must have at least this much free space percentage of the volume size. Example: if this value is 40, the pool has 40GiB free, then the max volume size allowed to be snapped on the pool is 100GiB. | `"40%"` | +| agents.​core.​capacity.​thin.​volumeCommitment | When creating replicas for an existing volume, each replica pool must have at least this much free space percentage of the volume size. Example: if this value is 40, the pool has 40GiB free, then the max volume size allowed to be created on the pool is 100GiB. | `"40%"` | +| agents.​core.​capacity.​thin.​volumeCommitmentInitial | Same as the `volumeCommitment` argument, but applicable only when creating replicas for a new volume. | `"40%"` | +| agents.​core.​encryptedPoolsSoftScheduling | Prefer encrypted pools for volume replicas. If a volume wasn't provisioned with a encryption storageclass, we try to place the replicas of such volume on best-effort basis onto encrypted pools, if this global is set. This is effective subject to volume spec already modified via plugin to request encryption. | `false` | +| agents.​core.​logLevel | Log level for the core service | `"info"` | +| agents.​core.​minTimeouts | Enable minimal timeouts | `true` | +| agents.​core.​poolClusterSize | Default blobstore cluster size for diskpools, in bytes. This value is used as a default value of blobstore cluster size on diskpools. This is set to 4MiB internally by default, if nothing specified here. The value is also configurable via Diskpool CR, which takes precedence over this setting. This is an advanced configuration, please refer documentation to understand the usage and implications of this. | `""` | +| agents.​core.​priorityClassName | Set PriorityClass, overrides global. If both local and global are not set, the final deployment manifest has a mayastor custom critical priority class assigned to the pod by default. Refer the `templates/_helpers.tpl` and `templates/mayastor/agents/core/agent-core-deployment.yaml` for more details. | `""` | +| agents.​core.​rebuild.​maxConcurrent | The maximum number of system-wide rebuilds permitted at any given time. If set to an empty string, there are no limits. | `""` | +| agents.​core.​rebuild.​partial.​enabled | Partial rebuild uses a log of missed IO to rebuild replicas which have become temporarily faulted, hence a bit faster, depending on the log size. | `true` | +| agents.​core.​rebuild.​partial.​waitPeriod | If a faulted replica comes back online within this time period then it will be rebuilt using the partial rebuild capability. Otherwise, the replica will be fully rebuilt. A blank value "" means internally derived value will be used. | `""` | +| agents.​core.​requestTimeout | Request timeout for core agents Default value is defined in .base.default_req_timeout | `nil` | +| agents.​core.​resources.​limits.​cpu | Cpu limits for core agents | `"1000m"` | +| agents.​core.​resources.​limits.​memory | Memory limits for core agents | `"128Mi"` | +| agents.​core.​resources.​requests.​cpu | Cpu requests for core agents | `"500m"` | +| agents.​core.​resources.​requests.​memory | Memory requests for core agents | `"32Mi"` | +| agents.​core.​tolerations | Set tolerations, overrides global | `[]` | +| agents.​core.​volumeHealth | Enable extended volume health information, which helps generate the volume status more accurately. | `true` | +| agents.​ha.​cluster.​logLevel | Log level for the ha cluster service | `"info"` | +| agents.​ha.​cluster.​resources.​limits.​cpu | Cpu limits for ha cluster agent | `"100m"` | +| agents.​ha.​cluster.​resources.​limits.​memory | Memory limits for ha cluster agent | `"64Mi"` | +| agents.​ha.​cluster.​resources.​requests.​cpu | Cpu requests for ha cluster agent | `"100m"` | +| agents.​ha.​cluster.​resources.​requests.​memory | Memory requests for ha cluster agent | `"16Mi"` | +| agents.​ha.​node.​logLevel | Log level for the ha node service | `"info"` | +| agents.​ha.​node.​port | Container port for the ha-node service | `50053` | +| agents.​ha.​node.​priorityClassName | Set PriorityClass, overrides global | `""` | +| agents.​ha.​node.​resources.​limits.​cpu | Cpu limits for ha node agent | `"100m"` | +| agents.​ha.​node.​resources.​limits.​memory | Memory limits for ha node agent | `"64Mi"` | +| agents.​ha.​node.​resources.​requests.​cpu | Cpu requests for ha node agent | `"100m"` | +| agents.​ha.​node.​resources.​requests.​memory | Memory requests for ha node agent | `"64Mi"` | +| agents.​ha.​node.​tolerations | Set tolerations, overrides global | `[]` | +| alloy.​logging_config.​labels | Labels to enable scraping on, at-least one of these labels should be present. |
{
"openebs.io/logging":true
}
| +| alloy.​logging_config.​tenant_id | X-Scope-OrgID to pe populated which pushing logs. Make sure the caller also uses the same. | `"openebs"` | +| apis.​rest.​healthProbes.​liveness.​enabled | Toggle liveness probe. | `true` | +| apis.​rest.​healthProbes.​liveness.​failureThreshold | No. of failures the liveness probe will tolerate. | `1` | +| apis.​rest.​healthProbes.​liveness.​initialDelaySeconds | No. of seconds of delay before checking the liveness status. | `0` | +| apis.​rest.​healthProbes.​liveness.​periodSeconds | No. of seconds between liveness probe checks. | `30` | +| apis.​rest.​healthProbes.​liveness.​timeoutSeconds | No. of seconds of timeout tolerance. | `5` | +| apis.​rest.​healthProbes.​readiness.​agentCoreProbeFreq | Frequency for the agent-core liveness probe. | `"20s"` | +| apis.​rest.​healthProbes.​readiness.​enabled | Toggle readiness probe. | `true` | +| apis.​rest.​healthProbes.​readiness.​failureThreshold | No. of failures the readiness probe will tolerate. | `2` | +| apis.​rest.​healthProbes.​readiness.​initialDelaySeconds | No. of seconds of delay before checking the readiness status. | `0` | +| apis.​rest.​healthProbes.​readiness.​periodSeconds | No. of seconds between readiness probe checks. | `20` | +| apis.​rest.​healthProbes.​readiness.​timeoutSeconds | No. of seconds of timeout tolerance. | `5` | +| apis.​rest.​logLevel | Log level for the rest service | `"info"` | +| apis.​rest.​priorityClassName | Set PriorityClass, overrides global. If both local and global are not set, the final deployment manifest has a mayastor custom critical priority class assigned to the pod by default. Refer the `templates/_helpers.tpl` and `templates/mayastor/apis/rest/api-rest-deployment.yaml` for more details. | `""` | +| apis.​rest.​replicaCount | Number of replicas of rest | `1` | +| apis.​rest.​resources.​limits.​cpu | Cpu limits for rest | `"100m"` | +| apis.​rest.​resources.​limits.​memory | Memory limits for rest | `"64Mi"` | +| apis.​rest.​resources.​requests.​cpu | Cpu requests for rest | `"50m"` | +| apis.​rest.​resources.​requests.​memory | Memory requests for rest | `"32Mi"` | +| apis.​rest.​service.​type | Rest K8s service type | `"ClusterIP"` | +| apis.​rest.​tolerations | Set tolerations, overrides global | `[]` | +| base.​cache_poll_period | Cache timeout for core agent & diskpool deployment | `"30s"` | +| base.​default_req_timeout | Request timeout for rest & core agents | `"5s"` | +| base.​logging.​color | Enable ansi color code for Pod StdOut/StdErr | `true` | +| base.​logging.​format | Valid values for format are pretty, json and compact | `"pretty"` | +| base.​logging.​silenceLevel | Silence specific module components | `nil` | +| base.​metrics.​enabled | Enable the metrics exporter | `true` | +| base.​metrics.​port | Container port for the metrics exporter service | `9502` | +| crds.​csi.​volumeSnapshots.​enabled | Install Volume Snapshot CRDs | `true` | +| crds.​enabled | Disables the installation of all CRDs if set to false | `true` | +| csi.​controller.​logLevel | Log level for the csi controller | `"info"` | +| csi.​controller.​preventVolumeModeConversion | Prevent modifying the volume mode when creating a PVC from an existing VolumeSnapshot | `true` | +| csi.​controller.​priorityClassName | Set PriorityClass, overrides global | `""` | +| csi.​controller.​resources.​limits.​cpu | Cpu limits for csi controller | `"32m"` | +| csi.​controller.​resources.​limits.​memory | Memory limits for csi controller | `"128Mi"` | +| csi.​controller.​resources.​requests.​cpu | Cpu requests for csi controller | `"16m"` | +| csi.​controller.​resources.​requests.​memory | Memory requests for csi controller | `"64Mi"` | +| csi.​controller.​tolerations | Set tolerations, overrides global | `[]` | +| csi.​image.​attacherTag | csi-attacher image release tag | `"v4.8.1"` | +| csi.​image.​provisionerTag | csi-provisioner image release tag | `"v5.2.0"` | +| csi.​image.​pullPolicy | imagePullPolicy for all CSI Sidecar images | `"IfNotPresent"` | +| csi.​image.​registrarTag | csi-node-driver-registrar image release tag | `"v2.13.0"` | +| csi.​image.​registry | Image registry to pull all CSI Sidecar images | `"registry.k8s.io"` | +| csi.​image.​repo | Image registry's namespace | `"sig-storage"` | +| csi.​image.​resizerTag | csi-resizer image release tag | `"v1.13.2"` | +| csi.​image.​snapshotControllerTag | csi-snapshot-controller image release tag | `"v8.2.0"` | +| csi.​image.​snapshotterTag | csi-snapshotter image release tag | `"v8.2.0"` | +| csi.​node.​kubeletDir | The kubeletDir directory for the csi-node plugin | `"/var/lib/kubelet"` | +| csi.​node.​nvme.​ctrl_loss_tmo | The ctrl_loss_tmo (controller loss timeout) in seconds | `"1980"` | +| csi.​node.​nvme.​tcpFallback | Fallback to nvme-tcp if nvme-rdma is enabled for Mayastor but rdma is not available on a particular csi-node | `true` | +| csi.​node.​port | Container port for the csi-node service | `10199` | +| csi.​node.​priorityClassName | Set PriorityClass, overrides global | `""` | +| csi.​node.​resources.​limits.​cpu | Cpu limits for csi node plugin | `"100m"` | +| csi.​node.​resources.​limits.​memory | Memory limits for csi node plugin | `"128Mi"` | +| csi.​node.​resources.​requests.​cpu | Cpu requests for csi node plugin | `"100m"` | +| csi.​node.​resources.​requests.​memory | Memory requests for csi node plugin | `"64Mi"` | +| csi.​node.​tolerations | Set tolerations, overrides global | `[]` | +| csi.​node.​topology.​nodeSelector | Add topology segments to the csi-node and agent-ha-node daemonset node selector | `false` | +| etcd.​autoCompactionMode | AutoCompaction Since etcd keeps an exact history of its keyspace, this history should be periodically compacted to avoid performance degradation and eventual storage space exhaustion. Auto compaction mode. Valid values: "periodic", "revision". - 'periodic' for duration based retention, defaulting to hours if no time unit is provided (e.g. 5m). - 'revision' for revision number based retention. | `"revision"` | +| etcd.​autoCompactionRetention | Auto compaction retention length. 0 means disable auto compaction. | `"100"` | +| etcd.​clusterDomain | Kubernetes Cluster Domain | `"cluster.local"` | +| etcd.​enabled | Disable when using an external etcd cluster. | `true` | +| etcd.​externalUrl | Url of the external etcd cluster. Note, etcd.enable must be set to false. | `""` | +| etcd.​extraEnvVars[0] | Raise alarms when backend size exceeds the given quota. |
{
"name":"ETCD_QUOTA_BACKEND_BYTES",
"value":"8589934592"
}
| +| etcd.​localpvScConfig.​basePath | Host path where local etcd data is stored in. | `"/var/local/{{ .Release.Name }}/localpv-hostpath/etcd"` | +| etcd.​localpvScConfig.​reclaimPolicy | ReclaimPolicy of etcd's localpv hostpath storage class. | `"Delete"` | +| etcd.​localpvScConfig.​volumeBindingMode | VolumeBindingMode of etcd's localpv hostpath storage class. | `"WaitForFirstConsumer"` | +| etcd.​persistence.​enabled | If true, use a Persistent Volume Claim. If false, use emptyDir. | `true` | +| etcd.​persistence.​size | Volume size | `"2Gi"` | +| etcd.​persistence.​storageClass | Will define which storageClass to use in etcd's StatefulSets. Options:

- `"manual"` - Will provision a hostpath PV on the same node.
- `""` (empty) - Will use the default StorageClass on the cluster.

| `"mayastor-etcd-localpv"` | +| etcd.​persistentVolumeClaimRetentionPolicy.​enabled | PVC's reclaimPolicy | `false` | +| etcd.​podAntiAffinityPreset | Pod anti-affinity preset Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity | `"hard"` | +| etcd.​removeMemberOnContainerTermination | Use a PreStop hook to remove the etcd members from the etcd cluster on container termination Ignored if lifecycleHooks is set or replicaCount=1 | `false` | +| etcd.​replicaCount | Number of replicas of etcd | `3` | +| image.​pullPolicy | ImagePullPolicy for our images | `"IfNotPresent"` | +| image.​pullSecrets | docker-secrets required to pull images if the container registry from image.registry is protected | `[]` | +| image.​registry | Image registry to pull our product images | `"docker.io"` | +| image.​repo | Image registry's namespace | `"openebs"` | +| image.​tag | Release tag for our images | `"v2.10.0"` | +| io_engine.​coreList | If not empty, overrides the cpuCount and explicitly sets the list of cores. Example: --set='io_engine.coreList={30,31}' | `[]` | +| io_engine.​cpuCount | The number of cores that each io-engine instance will bind to. | `"2"` | +| io_engine.​envcontext | Pass additional arguments to the Environment Abstraction Layer. Example: --set {product}.envcontext=iova-mode=pa | `""` | +| io_engine.​logLevel | Log level for the io-engine service | `"info"` | +| io_engine.​nodeSelector | Node selectors to designate storage nodes for diskpool creation Note that if multi-arch images support 'kubernetes.io/arch: amd64' should be removed. |
{
"kubernetes.io/arch":"amd64",
"openebs.io/engine":"mayastor"
}
| +| io_engine.​nvme.​ioTimeout | Timeout for IOs The default here is exaggerated for local disks, but we've observed that in shared virtual environments having a higher timeout value is beneficial. Please adjust this according to your hardware and needs. | `"110s"` | +| io_engine.​nvme.​tcp.​maxQueueDepth | You may need to increase this for a higher outstanding IOs per volume | `"32"` | +| io_engine.​port | Container port for the io-engine service | `10124` | +| io_engine.​priorityClassName | Set PriorityClass, overrides global | `""` | +| io_engine.​pstorRetries | Number of retries for pstor persistence before the volume target self shutdowns | `300` | +| io_engine.​resources.​limits.​cpu | Cpu limits for the io-engine | `""` | +| io_engine.​resources.​limits.​hugepages1Gi | Hugepage memory in 1GiB chunks | `nil` | +| io_engine.​resources.​limits.​hugepages2Mi | Hugepage memory in 2MiB chunks | `"2Gi"` | +| io_engine.​resources.​limits.​memory | Memory limits for the io-engine | `"1Gi"` | +| io_engine.​resources.​requests.​cpu | Cpu requests for the io-engine | `""` | +| io_engine.​resources.​requests.​hugepages1Gi | Hugepage memory in 1GiB chunks | `nil` | +| io_engine.​resources.​requests.​hugepages2Mi | Hugepage memory in 2MiB chunks | `"2Gi"` | +| io_engine.​resources.​requests.​memory | Memory requests for the io-engine | `"1Gi"` | +| io_engine.​runtimeClassName | Runtime class to use. Defaults to cluster standard | `""` | +| io_engine.​target.​nvmf.​iface | NVMF target interface (ip, mac, name or subnet) If RDMA is enabled, please set iface to an RDMA capable netdev name from host network. Example, if an rdma device mlx5_0 is available on a netdev eth0 on RNIC, as can be seen from `rdma link` command output, then this field should be set to eth0. | `""` | +| io_engine.​target.​nvmf.​ptpl | Reservations Persist Through Power Loss State | `true` | +| io_engine.​target.​nvmf.​rdma | Enable RDMA Capability of Mayastor nvmf target to take RDMA connections if the cluster nodes have RDMA device(s) configured from RNIC. |
{
"enabled":false
}
| +| io_engine.​tolerations | Set tolerations, overrides global | `[]` | +| localpv-provisioner.​enabled | Enables the openebs dynamic-localpv-provisioner. If disabled, modify etcd and loki storage class accordingly. | `true` | +| localpv-provisioner.​hostpathClass.​enabled | Enable default hostpath localpv StorageClass. | `false` | +| localpv-provisioner.​localpv.​priorityClassName | Set the PriorityClass for the LocalPV Hostpath provisioner Deployment. | `"{{ .Release.Name }}-cluster-critical"` | +| loki.​localpvScConfig.​loki.​basePath | Host path where local loki data is stored in. | `"/var/local/{{ .Release.Name }}/localpv-hostpath/loki"` | +| loki.​localpvScConfig.​loki.​reclaimPolicy | ReclaimPolicy of loki's localpv hostpath storage class. | `"Delete"` | +| loki.​localpvScConfig.​loki.​volumeBindingMode | VolumeBindingMode of loki's localpv hostpath storage class. | `"WaitForFirstConsumer"` | +| loki.​localpvScConfig.​minio.​basePath | Host path where local minio data is stored in. | `"/var/local/{{ .Release.Name }}/localpv-hostpath/minio"` | +| loki.​localpvScConfig.​minio.​reclaimPolicy | ReclaimPolicy of minio's localpv hostpath storage class. | `"Delete"` | +| loki.​localpvScConfig.​minio.​volumeBindingMode | VolumeBindingMode of minio's localpv hostpath storage class. | `"WaitForFirstConsumer"` | +| nodeSelector | Node labels for pod assignment ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ Note that if multi-arch images support 'kubernetes.io/arch: amd64' should be removed and set 'nodeSelector' to empty '{}' as default value. |
{
"kubernetes.io/arch":"amd64"
}
| +| obs.​callhome.​enabled | Enable callhome | `true` | +| obs.​callhome.​logLevel | Log level for callhome | `"info"` | +| obs.​callhome.​priorityClassName | Set PriorityClass, overrides global | `""` | +| obs.​callhome.​resources.​limits.​cpu | Cpu limits for callhome | `"100m"` | +| obs.​callhome.​resources.​limits.​memory | Memory limits for callhome | `"32Mi"` | +| obs.​callhome.​resources.​requests.​cpu | Cpu requests for callhome | `"50m"` | +| obs.​callhome.​resources.​requests.​memory | Memory requests for callhome | `"16Mi"` | +| obs.​callhome.​tolerations | Set tolerations, overrides global | `[]` | +| obs.​stats.​logLevel | Log level for stats | `"info"` | +| obs.​stats.​resources.​limits.​cpu | Cpu limits for stats | `"100m"` | +| obs.​stats.​resources.​limits.​memory | Memory limits for stats | `"32Mi"` | +| obs.​stats.​resources.​requests.​cpu | Cpu requests for stats | `"50m"` | +| obs.​stats.​resources.​requests.​memory | Memory requests for stats | `"16Mi"` | +| obs.​stats.​service.​type | Rest K8s service type | `"ClusterIP"` | +| operators.​pool.​logLevel | Log level for diskpool operator service | `"info"` | +| operators.​pool.​priorityClassName | Set PriorityClass, overrides global | `""` | +| operators.​pool.​resources.​limits.​cpu | Cpu limits for diskpool operator | `"100m"` | +| operators.​pool.​resources.​limits.​memory | Memory limits for diskpool operator | `"32Mi"` | +| operators.​pool.​resources.​requests.​cpu | Cpu requests for diskpool operator | `"50m"` | +| operators.​pool.​resources.​requests.​memory | Memory requests for diskpool operator | `"16Mi"` | +| operators.​pool.​tolerations | Set tolerations, overrides global | `[]` | +| preUpgradeHook.​enabled | Enable/Disable mayastor pre-upgrade hook | `true` | +| preUpgradeHook.​image.​pullPolicy | The imagePullPolicy for the container | `"IfNotPresent"` | +| preUpgradeHook.​image.​registry | The container image registry URL for the hook job | `"docker.io"` | +| preUpgradeHook.​image.​repo | The container repository for the hook job | `"openebs/kubectl"` | +| preUpgradeHook.​image.​tag | The container image tag for the hook job | `"1.25.15"` | +| preUpgradeHook.​imagePullSecrets | Optional array of imagePullSecrets containing private registry credentials # Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ | `[]` | +| preUpgradeHook.​tolerations | Node tolerations for server scheduling to nodes with taints # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ # | `[]` | +| priorityClassName | Pod scheduling priority. Setting this value will apply to all components except the external Chart dependencies. If any component has `priorityClassName` set, then this value would be overridden for that component. For external components like etcd, jaeger or loki, PriorityClass can only be set at component level. | `""` | +| storageClass.​allowVolumeExpansion | Enable volume expansion for the default StorageClass. | `true` | +| tolerations | Tolerations to be applied to all components except external Chart dependencies. If any component has tolerations set, then it would override this value. For external components like etcd, jaeger and loki, tolerations can only be set at component level. | `[]` | + diff --git a/charts/mayastor/charts/alloy/.helmignore b/charts/mayastor/charts/alloy/.helmignore new file mode 100644 index 0000000..da2093f --- /dev/null +++ b/charts/mayastor/charts/alloy/.helmignore @@ -0,0 +1,29 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ + +# Don't package templates. +README.md.gotmpl + +# Don't packages the tests used for CI. +/tests/ diff --git a/charts/mayastor/charts/alloy/CHANGELOG.md b/charts/mayastor/charts/alloy/CHANGELOG.md new file mode 100644 index 0000000..1623c85 --- /dev/null +++ b/charts/mayastor/charts/alloy/CHANGELOG.md @@ -0,0 +1,245 @@ +# Changelog + +> _Contributors should read our [contributors guide][] for instructions on how +> to update the changelog._ + +This document contains a historical list of changes between releases. Only +changes that impact end-user behavior are listed; changes to documentation or +internal API changes are not present. + +Unreleased +---------- + +1.0.1 (2025-04-10) +---------- + +### Enhancements + +- Update to Grafana Alloy v1.8.1. (@dehaansa) + +- Update default configreloader resources to match what is set in prometheus-operator project (@dehaansa) + +- Add Vertical Pod Autoscaler support (@QuentinBisson) + +1.0.0 (2025-04-09) +---------- + +### Enhancements + +- Update version to `1.0.0`. This Helm chart is now covered with the [backward-compatibility](https://grafana.com/docs/alloy/latest/introduction/backward-compatibility/) policy. + +- Update to Grafana Alloy v1.8.0. (@thampiotr) + +0.12.6 (2025-04-03) +---------- +### Breaking changes + +- configReloader.customArgs are likely to break as the prometheus maintained config reloader does not have the same arguments as the previous image (@dehaansa) + +### Enhancements + +- Change configReloader from jimmydyson/configmap-reload to prometheus-operator/prometheus-config-reloader (@dehaansa) +- Update to Grafana Alloy v1.7.5. (@kimxogus) +- Add `checksum/config` pod annotation (@kimxogus) + +### Other changes + +- Fix typo in values.yaml documentation (@petewall) + +0.12.5 (2025-03-13) +---------- +### Enhancements + +- Update to Grafana Alloy v1.7.4. (@dehaansa) + +0.12.4 (2025-03-13) +---------- +### Enhancements + +- Update to Grafana Alloy v1.7.3. (@dehaansa) + +0.12.3 (2025-03-10) +---------- + +### Enhancements + +- Add support for adding livenessProbe to agent container (@slimes28) + +0.12.2 (2025-03-10) +---------- + +### Bug Fixes + +- Set resource namespace correctly (@shinebayar-g) + +### Enhancements + +- Add a new `automountServiceAccountToken` configuration value for `serviceAccount`. (@ptodev) +- Update to Grafana Alloy v1.7.2. (@thampiotr) + +0.12.1 (2025-02-26) +---------- + +### Enhancements + +- Update to Grafana Alloy v1.7.1. (@thampiotr) + +0.12.0 (2025-02-24) +---------- + +### Enhancements + +- Update to Grafana Alloy v1.7.0. (@thampiotr) + +0.11.0 (2025-01-23) +---------- + +### Enhancements + +- Update jimmidyson/configmap-reload to 0.14.0. (@petewall) +- Add the ability to deploy extra manifest files. (@dbluxo) + +0.10.1 (2024-12-03) +---------- + +### Enhancements + +- Update to Grafana Alloy v1.5.1. (@ptodev) + +0.10.0 (2024-11-13) +---------- + +### Enhancements + +- Add support for adding hostAliases to the Helm chart. (@duncan485) +- Update to Grafana Alloy v1.5.0. (@thampiotr) + +0.9.2 (2024-10-18) +------------------ + +### Enhancements + +- Update to Grafana Alloy v1.4.3. (@ptodev) + +0.9.1 (2024-10-04) +------------------ + +### Enhancements + +- Update to Grafana Alloy v1.4.2. (@ptodev) + +0.9.0 (2024-10-02) +------------------ + +### Enhancements + +- Add lifecyle hook to the Helm chart. (@etiennep) +- Add terminationGracePeriodSeconds setting to the Helm chart. (@etiennep) + +0.8.1 (2024-09-26) +------------------ + +### Enhancements + +- Update to Grafana Alloy v1.4.1. (@ptodev) + +0.8.0 (2024-09-25) +------------------ + +### Enhancements + +- Update to Grafana Alloy v1.4.0. (@ptodev) + +0.7.0 (2024-08-26) +------------------ + +### Enhancements + +- Add PodDisruptionBudget to the Helm chart. (@itspouya) + +0.6.1 (2024-08-23) +---------- + +### Enhancements + +- Add the ability to set --cluster.name in the Helm chart with alloy.clustering.name. (@petewall) +- Add the ability to set appProtocol in extraPorts to help OpenShift users to expose gRPC. (@clementduveau) + +### Other changes + +- Update helm chart to use v1.3.1. + +0.6.0 (2024-08-05) +------------------ + +### Other changes + +- Update helm chart to use v1.3.0. + +- Set `publishNotReadyAddresses` to `true` in the service spec for clustering to fix a bug where peers could not join on startup. (@wildum) + +0.5.1 (2023-07-11) +------------------ + +### Other changes + +- Update helm chart to use v1.2.1. + +0.5.0 (2024-07-08) +------------------ + +### Enhancements + +- Only utilize spec.internalTrafficPolicy in the Service if deploying to Kubernetes 1.26 or later. (@petewall) + +0.4.0 (2024-06-26) +------------------ + +### Enhancements + +- Update to Grafana Alloy v1.2.0. (@ptodev) + +0.3.2 (2024-05-30) +------------------ + +### Bugfixes + +- Update to Grafana Alloy v1.1.1. (@rfratto) + +0.3.1 (2024-05-22) +------------------ + +### Bugfixes + +- Fix clustering on instances running within Istio mesh by allowing to change the name of the clustering port + +0.3.0 (2024-05-14) +------------------ + +### Enhancements + +- Update to Grafana Alloy v1.1.0. (@rfratto) + +0.2.0 (2024-05-08) +------------------ + +### Other changes + +- Support all [Kubernetes recommended labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/) (@nlamirault) + +0.1.1 (2024-04-11) +------------------ + +### Other changes + +- Add missing Alloy icon to Chart.yaml. (@rfratto) + +0.1.0 (2024-04-09) +------------------ + +### Features + +- Introduce a Grafana Alloy Helm chart. The Grafana Alloy Helm chart is + backwards compatibile with the values.yaml from the `grafana-agent` Helm + chart. Review the Helm chart README for a description on how to migrate. + (@rfratto) diff --git a/charts/mayastor/charts/alloy/Chart.lock b/charts/mayastor/charts/alloy/Chart.lock new file mode 100644 index 0000000..b459e48 --- /dev/null +++ b/charts/mayastor/charts/alloy/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: crds + repository: "" + version: 0.0.0 +digest: sha256:1980431a3d80822fca2e67e9cf16ff7a7f8d1dc87deb9e44d50e85e3e8e33a81 +generated: "2025-04-11T09:30:48.378858526Z" diff --git a/charts/mayastor/charts/alloy/Chart.yaml b/charts/mayastor/charts/alloy/Chart.yaml new file mode 100644 index 0000000..e23ca6f --- /dev/null +++ b/charts/mayastor/charts/alloy/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 +appVersion: v1.8.1 +dependencies: +- condition: crds.create + name: crds + repository: "" + version: 0.0.0 +description: Grafana Alloy +icon: https://raw.githubusercontent.com/grafana/alloy/main/docs/sources/assets/alloy_icon_orange.svg +name: alloy +type: application +version: 1.0.1 diff --git a/charts/mayastor/charts/alloy/README.md b/charts/mayastor/charts/alloy/README.md new file mode 100644 index 0000000..7492392 --- /dev/null +++ b/charts/mayastor/charts/alloy/README.md @@ -0,0 +1,342 @@ +# Grafana Alloy Helm chart + +![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 1.0.1](https://img.shields.io/badge/Version-1.0.1-informational?style=flat-square) ![AppVersion: v1.8.1](https://img.shields.io/badge/AppVersion-v1.8.1-informational?style=flat-square) + +Helm chart for deploying [Grafana Alloy][] to Kubernetes. + +[Grafana Alloy]: https://grafana.com/docs/alloy/latest/ + +## Usage + +### Setup Grafana chart repository + +``` +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +### Install chart + +To install the chart with the release name my-release: + +`helm install my-release grafana/alloy` + +This chart installs one instance of Grafana Alloy into your Kubernetes cluster +using a specific Kubernetes controller. By default, DaemonSet is used. The +`controller.type` value can be used to change the controller to either a +StatefulSet or Deployment. + +Creating multiple installations of the Helm chart with different controllers is +useful if just using the default DaemonSet isn't sufficient. + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| alloy.clustering.enabled | bool | `false` | Deploy Alloy in a cluster to allow for load distribution. | +| alloy.clustering.name | string | `""` | Name for the Alloy cluster. Used for differentiating between clusters. | +| alloy.clustering.portName | string | `"http"` | Name for the port used for clustering, useful if running inside an Istio Mesh | +| alloy.configMap.content | string | `""` | Content to assign to the new ConfigMap. This is passed into `tpl` allowing for templating from values. | +| alloy.configMap.create | bool | `true` | Create a new ConfigMap for the config file. | +| alloy.configMap.key | string | `nil` | Key in ConfigMap to get config from. | +| alloy.configMap.name | string | `nil` | Name of existing ConfigMap to use. Used when create is false. | +| alloy.enableReporting | bool | `true` | Enables sending Grafana Labs anonymous usage stats to help improve Grafana Alloy. | +| alloy.envFrom | list | `[]` | Maps all the keys on a ConfigMap or Secret as environment variables. https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#envfromsource-v1-core | +| alloy.extraArgs | list | `[]` | Extra args to pass to `alloy run`: https://grafana.com/docs/alloy/latest/reference/cli/run/ | +| alloy.extraEnv | list | `[]` | Extra environment variables to pass to the Alloy container. | +| alloy.extraPorts | list | `[]` | Extra ports to expose on the Alloy container. | +| alloy.hostAliases | list | `[]` | Host aliases to add to the Alloy container. | +| alloy.lifecycle | object | `{}` | Set lifecycle hooks for the Grafana Alloy container. | +| alloy.listenAddr | string | `"0.0.0.0"` | Address to listen for traffic on. 0.0.0.0 exposes the UI to other containers. | +| alloy.listenPort | int | `12345` | Port to listen for traffic on. | +| alloy.listenScheme | string | `"HTTP"` | Scheme is needed for readiness probes. If enabling tls in your configs, set to "HTTPS" | +| alloy.livenessProbe | object | `{}` | Set livenessProbe for the Grafana Alloy container. | +| alloy.mounts.dockercontainers | bool | `false` | Mount /var/lib/docker/containers from the host into the container for log collection. | +| alloy.mounts.extra | list | `[]` | Extra volume mounts to add into the Grafana Alloy container. Does not affect the watch container. | +| alloy.mounts.varlog | bool | `false` | Mount /var/log from the host into the container for log collection. | +| alloy.resources | object | `{}` | Resource requests and limits to apply to the Grafana Alloy container. | +| alloy.securityContext | object | `{}` | Security context to apply to the Grafana Alloy container. | +| alloy.stabilityLevel | string | `"generally-available"` | Minimum stability level of components and behavior to enable. Must be one of "experimental", "public-preview", or "generally-available". | +| alloy.storagePath | string | `"/tmp/alloy"` | Path to where Grafana Alloy stores data (for example, the Write-Ahead Log). By default, data is lost between reboots. | +| alloy.uiPathPrefix | string | `"/"` | Base path where the UI is exposed. | +| configReloader.customArgs | list | `[]` | Override the args passed to the container. | +| configReloader.enabled | bool | `true` | Enables automatically reloading when the Alloy config changes. | +| configReloader.image.digest | string | `""` | SHA256 digest of image to use for config reloading (either in format "sha256:XYZ" or "XYZ"). When set, will override `configReloader.image.tag` | +| configReloader.image.registry | string | `"quay.io"` | Config reloader image registry (defaults to docker.io) | +| configReloader.image.repository | string | `"prometheus-operator/prometheus-config-reloader"` | Repository to get config reloader image from. | +| configReloader.image.tag | string | `"v0.81.0"` | Tag of image to use for config reloading. | +| configReloader.resources | object | `{"requests":{"cpu":"10m","memory":"50Mi"}}` | Resource requests and limits to apply to the config reloader container. | +| configReloader.securityContext | object | `{}` | Security context to apply to the Grafana configReloader container. | +| controller.affinity | object | `{}` | Affinity configuration for pods. | +| controller.autoscaling.enabled | bool | `false` | Creates a HorizontalPodAutoscaler for controller type deployment. Deprecated: Please use controller.autoscaling.horizontal instead | +| controller.autoscaling.horizontal | object | `{"enabled":false,"maxReplicas":5,"minReplicas":1,"scaleDown":{"policies":[],"selectPolicy":"Max","stabilizationWindowSeconds":300},"scaleUp":{"policies":[],"selectPolicy":"Max","stabilizationWindowSeconds":0},"targetCPUUtilizationPercentage":0,"targetMemoryUtilizationPercentage":80}` | Configures the Horizontal Pod Autoscaler for the controller. | +| controller.autoscaling.horizontal.enabled | bool | `false` | Enables the Horizontal Pod Autoscaler for the controller. | +| controller.autoscaling.horizontal.maxReplicas | int | `5` | The upper limit for the number of replicas to which the autoscaler can scale up. | +| controller.autoscaling.horizontal.minReplicas | int | `1` | The lower limit for the number of replicas to which the autoscaler can scale down. | +| controller.autoscaling.horizontal.scaleDown.policies | list | `[]` | List of policies to determine the scale-down behavior. | +| controller.autoscaling.horizontal.scaleDown.selectPolicy | string | `"Max"` | Determines which of the provided scaling-down policies to apply if multiple are specified. | +| controller.autoscaling.horizontal.scaleDown.stabilizationWindowSeconds | int | `300` | The duration that the autoscaling mechanism should look back on to make decisions about scaling down. | +| controller.autoscaling.horizontal.scaleUp.policies | list | `[]` | List of policies to determine the scale-up behavior. | +| controller.autoscaling.horizontal.scaleUp.selectPolicy | string | `"Max"` | Determines which of the provided scaling-up policies to apply if multiple are specified. | +| controller.autoscaling.horizontal.scaleUp.stabilizationWindowSeconds | int | `0` | The duration that the autoscaling mechanism should look back on to make decisions about scaling up. | +| controller.autoscaling.horizontal.targetCPUUtilizationPercentage | int | `0` | Average CPU utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetCPUUtilizationPercentage` to 0 will disable CPU scaling. | +| controller.autoscaling.horizontal.targetMemoryUtilizationPercentage | int | `80` | Average Memory utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetMemoryUtilizationPercentage` to 0 will disable Memory scaling. | +| controller.autoscaling.maxReplicas | int | `5` | The upper limit for the number of replicas to which the autoscaler can scale up. | +| controller.autoscaling.minReplicas | int | `1` | The lower limit for the number of replicas to which the autoscaler can scale down. | +| controller.autoscaling.scaleDown.policies | list | `[]` | List of policies to determine the scale-down behavior. | +| controller.autoscaling.scaleDown.selectPolicy | string | `"Max"` | Determines which of the provided scaling-down policies to apply if multiple are specified. | +| controller.autoscaling.scaleDown.stabilizationWindowSeconds | int | `300` | The duration that the autoscaling mechanism should look back on to make decisions about scaling down. | +| controller.autoscaling.scaleUp.policies | list | `[]` | List of policies to determine the scale-up behavior. | +| controller.autoscaling.scaleUp.selectPolicy | string | `"Max"` | Determines which of the provided scaling-up policies to apply if multiple are specified. | +| controller.autoscaling.scaleUp.stabilizationWindowSeconds | int | `0` | The duration that the autoscaling mechanism should look back on to make decisions about scaling up. | +| controller.autoscaling.targetCPUUtilizationPercentage | int | `0` | Average CPU utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetCPUUtilizationPercentage` to 0 will disable CPU scaling. | +| controller.autoscaling.targetMemoryUtilizationPercentage | int | `80` | Average Memory utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetMemoryUtilizationPercentage` to 0 will disable Memory scaling. | +| controller.autoscaling.vertical | object | `{"enabled":false,"recommenders":[],"resourcePolicy":{"containerPolicies":[{"containerName":"alloy","controlledResources":["cpu","memory"],"controlledValues":"RequestsAndLimits","maxAllowed":{},"minAllowed":{}}]},"updatePolicy":null}` | Configures the Vertical Pod Autoscaler for the controller. | +| controller.autoscaling.vertical.enabled | bool | `false` | Enables the Vertical Pod Autoscaler for the controller. | +| controller.autoscaling.vertical.recommenders | list | `[]` | List of recommenders to use for the Vertical Pod Autoscaler. Recommenders are responsible for generating recommendation for the object. List should be empty (then the default recommender will generate the recommendation) or contain exactly one recommender. | +| controller.autoscaling.vertical.resourcePolicy | object | `{"containerPolicies":[{"containerName":"alloy","controlledResources":["cpu","memory"],"controlledValues":"RequestsAndLimits","maxAllowed":{},"minAllowed":{}}]}` | Configures the resource policy for the Vertical Pod Autoscaler. | +| controller.autoscaling.vertical.resourcePolicy.containerPolicies | list | `[{"containerName":"alloy","controlledResources":["cpu","memory"],"controlledValues":"RequestsAndLimits","maxAllowed":{},"minAllowed":{}}]` | Configures the container policies for the Vertical Pod Autoscaler. | +| controller.autoscaling.vertical.resourcePolicy.containerPolicies[0].controlledResources | list | `["cpu","memory"]` | The controlled resources for the Vertical Pod Autoscaler. | +| controller.autoscaling.vertical.resourcePolicy.containerPolicies[0].controlledValues | string | `"RequestsAndLimits"` | The controlled values for the Vertical Pod Autoscaler. Needs to be either RequestsOnly or RequestsAndLimits. | +| controller.autoscaling.vertical.resourcePolicy.containerPolicies[0].maxAllowed | object | `{}` | The maximum allowed values for the pods. | +| controller.autoscaling.vertical.resourcePolicy.containerPolicies[0].minAllowed | object | `{}` | Defines the min allowed resources for the pod | +| controller.autoscaling.vertical.updatePolicy | string | `nil` | Configures the update policy for the Vertical Pod Autoscaler. | +| controller.dnsPolicy | string | `"ClusterFirst"` | Configures the DNS policy for the pod. https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy | +| controller.enableStatefulSetAutoDeletePVC | bool | `false` | Whether to enable automatic deletion of stale PVCs due to a scale down operation, when controller.type is 'statefulset'. | +| controller.extraAnnotations | object | `{}` | Annotations to add to controller. | +| controller.extraContainers | list | `[]` | Additional containers to run alongside the Alloy container and initContainers. | +| controller.hostNetwork | bool | `false` | Configures Pods to use the host network. When set to true, the ports that will be used must be specified. | +| controller.hostPID | bool | `false` | Configures Pods to use the host PID namespace. | +| controller.initContainers | list | `[]` | | +| controller.nodeSelector | object | `{}` | nodeSelector to apply to Grafana Alloy pods. | +| controller.parallelRollout | bool | `true` | Whether to deploy pods in parallel. Only used when controller.type is 'statefulset'. | +| controller.podAnnotations | object | `{}` | Extra pod annotations to add. | +| controller.podDisruptionBudget | object | `{"enabled":false,"maxUnavailable":null,"minAvailable":null}` | PodDisruptionBudget configuration. | +| controller.podDisruptionBudget.enabled | bool | `false` | Whether to create a PodDisruptionBudget for the controller. | +| controller.podDisruptionBudget.maxUnavailable | string | `nil` | Maximum number of pods that can be unavailable during a disruption. Note: Only one of minAvailable or maxUnavailable should be set. | +| controller.podDisruptionBudget.minAvailable | string | `nil` | Minimum number of pods that must be available during a disruption. Note: Only one of minAvailable or maxUnavailable should be set. | +| controller.podLabels | object | `{}` | Extra pod labels to add. | +| controller.priorityClassName | string | `""` | priorityClassName to apply to Grafana Alloy pods. | +| controller.replicas | int | `1` | Number of pods to deploy. Ignored when controller.type is 'daemonset'. | +| controller.terminationGracePeriodSeconds | string | `nil` | Termination grace period in seconds for the Grafana Alloy pods. The default value used by Kubernetes if unspecifed is 30 seconds. | +| controller.tolerations | list | `[]` | Tolerations to apply to Grafana Alloy pods. | +| controller.topologySpreadConstraints | list | `[]` | Topology Spread Constraints to apply to Grafana Alloy pods. | +| controller.type | string | `"daemonset"` | Type of controller to use for deploying Grafana Alloy in the cluster. Must be one of 'daemonset', 'deployment', or 'statefulset'. | +| controller.updateStrategy | object | `{}` | Update strategy for updating deployed Pods. | +| controller.volumeClaimTemplates | list | `[]` | volumeClaimTemplates to add when controller.type is 'statefulset'. | +| controller.volumes.extra | list | `[]` | Extra volumes to add to the Grafana Alloy pod. | +| crds.create | bool | `true` | Whether to install CRDs for monitoring. | +| extraObjects | list | `[]` | Extra k8s manifests to deploy | +| fullnameOverride | string | `nil` | Overrides the chart's computed fullname. Used to change the full prefix of resource names. | +| global.image.pullSecrets | list | `[]` | Optional set of global image pull secrets. | +| global.image.registry | string | `""` | Global image registry to use if it needs to be overridden for some specific use cases (e.g local registries, custom images, ...) | +| global.podSecurityContext | object | `{}` | Security context to apply to the Grafana Alloy pod. | +| image.digest | string | `nil` | Grafana Alloy image's SHA256 digest (either in format "sha256:XYZ" or "XYZ"). When set, will override `image.tag`. | +| image.pullPolicy | string | `"IfNotPresent"` | Grafana Alloy image pull policy. | +| image.pullSecrets | list | `[]` | Optional set of image pull secrets. | +| image.registry | string | `"docker.io"` | Grafana Alloy image registry (defaults to docker.io) | +| image.repository | string | `"grafana/alloy"` | Grafana Alloy image repository. | +| image.tag | string | `nil` | Grafana Alloy image tag. When empty, the Chart's appVersion is used. | +| ingress.annotations | object | `{}` | | +| ingress.enabled | bool | `false` | Enables ingress for Alloy (Faro port) | +| ingress.extraPaths | list | `[]` | | +| ingress.faroPort | int | `12347` | | +| ingress.hosts[0] | string | `"chart-example.local"` | | +| ingress.labels | object | `{}` | | +| ingress.path | string | `"/"` | | +| ingress.pathType | string | `"Prefix"` | | +| ingress.tls | list | `[]` | | +| nameOverride | string | `nil` | Overrides the chart's name. Used to change the infix in the resource names. | +| namespaceOverride | string | `nil` | Overrides the chart's namespace. | +| rbac.create | bool | `true` | Whether to create RBAC resources for Alloy. | +| service.annotations | object | `{}` | | +| service.clusterIP | string | `""` | Cluster IP, can be set to None, empty "" or an IP address | +| service.enabled | bool | `true` | Creates a Service for the controller's pods. | +| service.internalTrafficPolicy | string | `"Cluster"` | Value for internal traffic policy. 'Cluster' or 'Local' | +| service.nodePort | int | `31128` | NodePort port. Only takes effect when `service.type: NodePort` | +| service.type | string | `"ClusterIP"` | Service type | +| serviceAccount.additionalLabels | object | `{}` | Additional labels to add to the created service account. | +| serviceAccount.annotations | object | `{}` | Annotations to add to the created service account. | +| serviceAccount.automountServiceAccountToken | bool | `true` | | +| serviceAccount.create | bool | `true` | Whether to create a service account for the Grafana Alloy deployment. | +| serviceAccount.name | string | `nil` | The name of the existing service account to use when serviceAccount.create is false. | +| serviceMonitor.additionalLabels | object | `{}` | Additional labels for the service monitor. | +| serviceMonitor.enabled | bool | `false` | | +| serviceMonitor.interval | string | `""` | Scrape interval. If not set, the Prometheus default scrape interval is used. | +| serviceMonitor.metricRelabelings | list | `[]` | MetricRelabelConfigs to apply to samples after scraping, but before ingestion. ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig | +| serviceMonitor.relabelings | list | `[]` | RelabelConfigs to apply to samples before scraping ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig | +| serviceMonitor.tlsConfig | object | `{}` | Customize tls parameters for the service monitor | + +#### Migrate from `grafana/grafana-agent` chart to `grafana/alloy` + +The `values.yaml` file for the `grafana/grafana-agent` chart is compatible with +the chart for `grafana/alloy`, with two exceptions: + +* The `agent` field in `values.yaml` is deprecated in favor of `alloy`. Support + for the `agent` field will be removed in a future release. + +* The default value for `alloy.listenPort` is `12345` to align with the default + listen port in other installations. To retain the previous default, set + `alloy.listenPort` to `80` when installing. + +### alloy.stabilityLevel + +`alloy.stabilityLevel` controls the minimum level of stability for what +components can be created (directly or through imported modules). Note that +setting this field to a lower stability may also enable internal behaviour of a +lower stability, such as experimental memory optimizations. + +Valid settings are `experimental`, `public-preview`, and `generally-available`. + +### alloy.extraArgs + +`alloy.extraArgs` allows for passing extra arguments to the Grafana Alloy +container. The list of available arguments is documented on [alloy run][]. + +> **WARNING**: Using `alloy.extraArgs` does not have a stable API. Things may +> break between Chart upgrade if an argument gets added to the template. + +[alloy run]: https://grafana.com/docs/alloy/latest/reference/cli/run/ + +### alloy.extraPorts + +`alloy.extraPorts` allows for configuring specific open ports. + +The detained specification of ports can be found at the [Kubernetes Pod documents](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#ports). + +Port numbers specified must be 0 < x < 65535. + +| ChartPort | KubePort | Description | +|-----------|----------|-------------| +| targetPort | containerPort | Number of port to expose on the pod's IP address. | +| hostPort | hostPort | (Optional) Number of port to expose on the host. Daemonsets taking traffic might find this useful. | +| name | name | If specified, this must be an `IANA_SVC_NAME` and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. +| protocol | protocol | Must be UDP, TCP, or SCTP. Defaults to "TCP". | +| appProtocol | appProtocol | Hint on application protocol. This is used to expose Alloy externally on OpenShift clusters using "h2c". Optional. No default value. | + +### alloy.listenAddr + +`alloy.listenAddr` allows for restricting which address Alloy listens on +for network traffic on its HTTP server. By default, this is `0.0.0.0` to allow +its UI to be exposed when port-forwarding and to expose its metrics to other +Alloy instances in the cluster. + +### alloy.configMap.config + +`alloy.configMap.content` holds the Grafana Alloy configuration to use. + +If `alloy.configMap.content` is not provided, a [default configuration file][default-config] is +used. When provided, `alloy.configMap.content` must hold a valid Alloy configuration file. + +[default-config]: ./config/example.alloy + +### alloy.securityContext + +`alloy.securityContext` sets the securityContext passed to the Grafana +Alloy container. + +By default, Grafana Alloy containers are not able to collect telemetry from the +host node or other specific types of privileged telemetry data. See [Collecting +logs from other containers][#collecting-logs-from-other-containers] and +[Collecting host node telemetry][#collecting-host-node-telemetry] below for +more information on how to enable these capabilities. + +### rbac.create + +`rbac.create` enables the creation of ClusterRole and ClusterRoleBindings for +the Grafana Alloy containers to use. The default permission set allows +components like [discovery.kubernetes][] to work properly. + +[discovery.kubernetes]: https://grafana.com/docs/alloy/latest/reference/components/discovery.kubernetes/ + +### controller.autoscaling + +`controller.autoscaling.enabled` enables the creation of a HorizontalPodAutoscaler. It is only used when `controller.type` is set to `deployment` or `statefulset`. + +`controller.autoscaling` is intended to be used with [clustered][] mode. + +> **WARNING**: Using `controller.autoscaling` for any other Grafana Alloy +> configuration could lead to redundant or double telemetry collection. + +[clustered]: https://grafana.com/docs/alloy/latest/reference/cli/run/#clustered-mode + +When using autoscaling with a StatefulSet controller and have enabled +volumeClaimTemplates to be created alongside the StatefulSet, it is possible to +leak up to `maxReplicas` PVCs when the HPA is scaling down. If you're on +Kubernetes version `>=1.23-0` and your cluster has the +`StatefulSetAutoDeletePVC` feature gate enabled, you can set +`enableStatefulSetAutoDeletePVC` to true to automatically delete stale PVCs. + +Using `controller.autoscaling` requires the target metric (cpu/memory) to have +its resource requests set up for both the Alloy and config-reloader containers +so that the HPA can use them to calculate the replica count from the actual +resource utilization. + +## Collecting logs from other containers + +There are two ways to collect logs from other containers within the cluster +Alloy is deployed in. + +### loki.source.kubernetes + +The [loki.source.kubernetes][] component may be used to collect logs from +containers using the Kubernetes API. This component does not require mounting +the hosts filesystem into Alloy, nor requires additional security contexts to +work correctly. + +[loki.source.kubernetes]: https://grafana.com/docs/alloy/latest/reference/components/loki.source.kubernetes/ + +### File-based collection + +Logs may also be collected by mounting the host's filesystem into the Alloy +container, bypassing the need to communicate with the Kubrnetes API. + +To mount logs from other containers to Grafana Alloy directly: + +* Set `alloy.mounts.dockercontainers` to `true`. +* Set `alloy.securityContext` to: + ```yaml + privileged: true + runAsUser: 0 + ``` + +## Collecting host node telemetry + +Telemetry from the host, such as host-specific log files (from `/var/logs`) or +metrics from `/proc` and `/sys` are not accessible to Grafana Alloy containers. + +To expose this information to Grafana Alloy for telemetry collection: + +* Set `alloy.mounts.dockercontainers` to `true`. +* Mount `/proc` and `/sys` from the host into the container. +* Set `alloy.securityContext` to: + ```yaml + privileged: true + runAsUser: 0 + ``` + +## Expose Alloy externally on OpenShift clusters + +If you want to send telemetry from an Alloy instance outside of the OpenShift clusters over gRPC towards the Alloy instance on the OpenShift clusters, you need to: + +* Set the optional `appProtocol` on `alloy.extraPorts` to `h2c` +* Expose the service via Ingress or Route within the OpenShift cluster. Example of a Route in OpenShift: +```yaml +kind: Route +apiVersion: route.openshift.io/v1 +metadata: + name: route-otlp-alloy-h2c +spec: + to: + kind: Service + name: test-grpc-h2c + weight: 100 + port: + targetPort: otlp-grpc + tls: + termination: edge + insecureEdgeTerminationPolicy: Redirect + wildcardPolicy: None +``` + +Once this Ingress/Route is exposed it would then allow gRPC communication for (for example) traces. This allow an Alloy instance on a VM or another Kubernetes/OpenShift cluster to be able to communicate over gRPC via the exposed Ingress or Route. \ No newline at end of file diff --git a/charts/mayastor/charts/alloy/charts/crds/Chart.yaml b/charts/mayastor/charts/alloy/charts/crds/Chart.yaml new file mode 100644 index 0000000..adb9e4a --- /dev/null +++ b/charts/mayastor/charts/alloy/charts/crds/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: crds +version: 0.0.0 diff --git a/charts/mayastor/charts/alloy/charts/crds/crds/monitoring.grafana.com_podlogs.yaml b/charts/mayastor/charts/alloy/charts/crds/crds/monitoring.grafana.com_podlogs.yaml new file mode 100644 index 0000000..7867832 --- /dev/null +++ b/charts/mayastor/charts/alloy/charts/crds/crds/monitoring.grafana.com_podlogs.yaml @@ -0,0 +1,205 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: podlogs.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - grafana-alloy + - alloy + kind: PodLogs + listKind: PodLogsList + plural: podlogs + singular: podlogs + scope: Namespaced + versions: + - name: v1alpha2 + schema: + openAPIV3Schema: + description: PodLogs defines how to collect logs for a Pod. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: PodLogsSpec defines how to collect logs for a Pod. + properties: + namespaceSelector: + description: Selector to select which namespaces the Pod objects are + discovered from. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + relabelings: + description: RelabelConfigs to apply to logs before delivering. + items: + description: 'RelabelConfig allows dynamic rewriting of the label + set, being applied to samples before ingestion. It defines ``-section + of Prometheus configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on regex matching. Default + is 'replace'. uppercase and lowercase actions require Prometheus + >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + type: string + modulus: + description: Modulus to take of the hash of the source label + values. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. Default is '(.*)' + type: string + replacement: + description: Replacement value against which a regex replace + is performed if the regular expression matches. Regex capture + groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated source label + values. default is ';'. + type: string + sourceLabels: + description: The source labels select values from existing labels. + Their content is concatenated using the configured separator + and matched against the configured regular expression for + the replace, keep, and drop actions. + items: + description: LabelName is a valid Prometheus label name which + may only contain ASCII letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting value is written in + a replace action. It is mandatory for replace actions. Regex + capture groups are available. + type: string + type: object + type: array + selector: + description: Selector to select Pod objects. Required. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - selector + type: object + type: object + served: true + storage: true diff --git a/charts/mayastor/charts/alloy/ci/additional-serviceaccount-label-values.yaml b/charts/mayastor/charts/alloy/ci/additional-serviceaccount-label-values.yaml new file mode 100644 index 0000000..91b7cbb --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/additional-serviceaccount-label-values.yaml @@ -0,0 +1,3 @@ +serviceAccount: + additionalLabels: + test: "true" diff --git a/charts/mayastor/charts/alloy/ci/clustering-values.yaml b/charts/mayastor/charts/alloy/ci/clustering-values.yaml new file mode 100644 index 0000000..4a0c468 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/clustering-values.yaml @@ -0,0 +1,7 @@ +alloy: + clustering: + enabled: true + +controller: + type: 'statefulset' + replicas: 3 diff --git a/charts/mayastor/charts/alloy/ci/controller-deployment-pdb-max-unavailable-values.yaml b/charts/mayastor/charts/alloy/ci/controller-deployment-pdb-max-unavailable-values.yaml new file mode 100644 index 0000000..1bddddc --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/controller-deployment-pdb-max-unavailable-values.yaml @@ -0,0 +1,5 @@ +controller: + type: deployment + podDisruptionBudget: + enabled: true + maxUnavailable: 1 diff --git a/charts/mayastor/charts/alloy/ci/controller-deployment-pdb-min-available-values.yaml b/charts/mayastor/charts/alloy/ci/controller-deployment-pdb-min-available-values.yaml new file mode 100644 index 0000000..f9879cc --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/controller-deployment-pdb-min-available-values.yaml @@ -0,0 +1,5 @@ +controller: + type: deployment + podDisruptionBudget: + enabled: true + minAvailable: 1 diff --git a/charts/mayastor/charts/alloy/ci/controller-statefulset-pdb-max-unavailable-values.yaml b/charts/mayastor/charts/alloy/ci/controller-statefulset-pdb-max-unavailable-values.yaml new file mode 100644 index 0000000..0aaf358 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/controller-statefulset-pdb-max-unavailable-values.yaml @@ -0,0 +1,5 @@ +controller: + type: statefulset + podDisruptionBudget: + enabled: true + maxUnavailable: 1 diff --git a/charts/mayastor/charts/alloy/ci/controller-statefulset-pdb-min-available-values.yaml b/charts/mayastor/charts/alloy/ci/controller-statefulset-pdb-min-available-values.yaml new file mode 100644 index 0000000..b8dbcbf --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/controller-statefulset-pdb-min-available-values.yaml @@ -0,0 +1,5 @@ +controller: + type: statefulset + podDisruptionBudget: + enabled: true + minAvailable: 1 diff --git a/charts/mayastor/charts/alloy/ci/controller-volumes-extra-values.yaml b/charts/mayastor/charts/alloy/ci/controller-volumes-extra-values.yaml new file mode 100644 index 0000000..2486c59 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/controller-volumes-extra-values.yaml @@ -0,0 +1,12 @@ +controller: + volumes: + extra: + - name: cache-volume + emptyDir: + sizeLimit: 500Mi + +alloy: + mounts: + extra: + - mountPath: /cache + name: cache-volume diff --git a/charts/mayastor/charts/alloy/ci/create-daemonset-hostnetwork-values.yaml b/charts/mayastor/charts/alloy/ci/create-daemonset-hostnetwork-values.yaml new file mode 100644 index 0000000..61d05b1 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/create-daemonset-hostnetwork-values.yaml @@ -0,0 +1,5 @@ +# Test rendering of the chart with the controller explicitly set to DaemonSet. +controller: + type: daemonset + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet diff --git a/charts/mayastor/charts/alloy/ci/create-daemonset-values.yaml b/charts/mayastor/charts/alloy/ci/create-daemonset-values.yaml new file mode 100644 index 0000000..13b7a39 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/create-daemonset-values.yaml @@ -0,0 +1,3 @@ +# Test rendering of the chart with the controller explicitly set to DaemonSet. +controller: + type: daemonset diff --git a/charts/mayastor/charts/alloy/ci/create-deployment-autoscaling-values.yaml b/charts/mayastor/charts/alloy/ci/create-deployment-autoscaling-values.yaml new file mode 100644 index 0000000..2db66b8 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/create-deployment-autoscaling-values.yaml @@ -0,0 +1,26 @@ +# Test rendering of the chart with the controller explicitly set to Deployment and autoscaling enabled. +controller: + type: deployment + autoscaling: + horizontal: + enabled: true + scaleDown: + policies: + - type: Pods + value: 4 + periodSeconds: 60 + selectPolicy: Min + stabilizationWindowSeconds: 100 + scaleUp: + policies: + - type: Pods + value: 4 + periodSeconds: 60 + - type: Percent + value: 100 + periodSeconds: 15 + stabilizationWindowSeconds: 80 +alloy: + resources: + requests: + memory: 100Mi diff --git a/charts/mayastor/charts/alloy/ci/create-deployment-values.yaml b/charts/mayastor/charts/alloy/ci/create-deployment-values.yaml new file mode 100644 index 0000000..4763b4b --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/create-deployment-values.yaml @@ -0,0 +1,3 @@ +# Test rendering of the chart with the controller explicitly set to Deployment. +controller: + type: deployment diff --git a/charts/mayastor/charts/alloy/ci/create-statefulset-autoscaling-values.yaml b/charts/mayastor/charts/alloy/ci/create-statefulset-autoscaling-values.yaml new file mode 100644 index 0000000..7ab438e --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/create-statefulset-autoscaling-values.yaml @@ -0,0 +1,26 @@ +# Test rendering of the chart with the controller explicitly set to StatefulSet and autoscaling the old way enabled. +controller: + type: statefulset + autoscaling: + enabled: true + scaleDown: + policies: + - type: Pods + value: 4 + periodSeconds: 60 + selectPolicy: Min + stabilizationWindowSeconds: 100 + scaleUp: + policies: + - type: Pods + value: 4 + periodSeconds: 60 + - type: Percent + value: 100 + periodSeconds: 15 + stabilizationWindowSeconds: 80 + enableStatefulSetAutoDeletePVC: true +alloy: + resources: + requests: + memory: 100Mi diff --git a/charts/mayastor/charts/alloy/ci/create-statefulset-values.yaml b/charts/mayastor/charts/alloy/ci/create-statefulset-values.yaml new file mode 100644 index 0000000..51c7c19 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/create-statefulset-values.yaml @@ -0,0 +1,3 @@ +# Test rendering of the chart with the controller explicitly set to StatefulSet. +controller: + type: statefulset diff --git a/charts/mayastor/charts/alloy/ci/custom-config-values.yaml b/charts/mayastor/charts/alloy/ci/custom-config-values.yaml new file mode 100644 index 0000000..ebfce09 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/custom-config-values.yaml @@ -0,0 +1,10 @@ +alloy: + configMap: + content: |- + logging { + level = "warn" + format = "logfmt" + } + discovery.kubernetes "custom_pods" { + role = "pod" + } diff --git a/charts/mayastor/charts/alloy/ci/default-values-values.yaml b/charts/mayastor/charts/alloy/ci/default-values-values.yaml new file mode 100644 index 0000000..3724bea --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/default-values-values.yaml @@ -0,0 +1 @@ +# Test rendering of the chart with everything set to the default values. diff --git a/charts/mayastor/charts/alloy/ci/enable-servicemonitor-tls-values.yaml b/charts/mayastor/charts/alloy/ci/enable-servicemonitor-tls-values.yaml new file mode 100644 index 0000000..26662f3 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/enable-servicemonitor-tls-values.yaml @@ -0,0 +1,9 @@ +# Test rendering of the chart with the service monitor enabled +alloy: + listenScheme: HTTPS +service: + enabled: true +serviceMonitor: + enabled: true + tlsConfig: + insecureSkipVerify: true diff --git a/charts/mayastor/charts/alloy/ci/enable-servicemonitor-values.yaml b/charts/mayastor/charts/alloy/ci/enable-servicemonitor-values.yaml new file mode 100644 index 0000000..837bf3f --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/enable-servicemonitor-values.yaml @@ -0,0 +1,5 @@ +# Test rendering of the chart with the service monitor enabled +service: + enabled: true +serviceMonitor: + enabled: true diff --git a/charts/mayastor/charts/alloy/ci/envFrom-values.yaml b/charts/mayastor/charts/alloy/ci/envFrom-values.yaml new file mode 100644 index 0000000..8d90148 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/envFrom-values.yaml @@ -0,0 +1,5 @@ +# Specify extra ports for verifying rendering the template works +alloy: + envFrom: + - configMapRef: + name: special-config diff --git a/charts/mayastor/charts/alloy/ci/existing-config-values.yaml b/charts/mayastor/charts/alloy/ci/existing-config-values.yaml new file mode 100644 index 0000000..5eeeb42 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/existing-config-values.yaml @@ -0,0 +1,5 @@ +alloy: + configMap: + create: false + name: existing-config + key: my-config.alloy diff --git a/charts/mayastor/charts/alloy/ci/extra-env-values.yaml b/charts/mayastor/charts/alloy/ci/extra-env-values.yaml new file mode 100644 index 0000000..7d444f1 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/extra-env-values.yaml @@ -0,0 +1,9 @@ +# Specify extra ports for verifying rendering the template works +alloy: + extraEnv: + - name: GREETING + value: "Warm greetings to" + - name: HONORIFIC + value: "The Most Honorable" + - name: NAME + value: "Kubernetes" diff --git a/charts/mayastor/charts/alloy/ci/extra-manifests-values.yaml b/charts/mayastor/charts/alloy/ci/extra-manifests-values.yaml new file mode 100644 index 0000000..324c44a --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/extra-manifests-values.yaml @@ -0,0 +1,8 @@ +extraObjects: +- apiVersion: v1 + kind: Secret + metadata: + name: grafana-cloud + stringData: + PROMETHEUS_HOST: 'https://prometheus-us-central1.grafana.net/api/prom/push' + PROMETHEUS_USERNAME: '123456' diff --git a/charts/mayastor/charts/alloy/ci/extra-ports-values.yaml b/charts/mayastor/charts/alloy/ci/extra-ports-values.yaml new file mode 100644 index 0000000..d29a0e5 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/extra-ports-values.yaml @@ -0,0 +1,7 @@ +# Specify extra ports for verifying rendering the template works +alloy: + extraPorts: + - name: jaeger-thrift + port: 14268 + targetPort: 14268 + protocol: TCP diff --git a/charts/mayastor/charts/alloy/ci/faro-ingress-values.yaml b/charts/mayastor/charts/alloy/ci/faro-ingress-values.yaml new file mode 100644 index 0000000..3f09d88 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/faro-ingress-values.yaml @@ -0,0 +1,9 @@ +alloy: + extraPorts: + - name: "faro" + port: 12347 + targetPort: 12347 + protocol: "TCP" + +ingress: + enabled: true diff --git a/charts/mayastor/charts/alloy/ci/global-image-pullsecrets-values.yaml b/charts/mayastor/charts/alloy/ci/global-image-pullsecrets-values.yaml new file mode 100644 index 0000000..30069cf --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/global-image-pullsecrets-values.yaml @@ -0,0 +1,13 @@ +# Test rendering of the chart with the global image pull secret explicitly set. +global: + image: + pullSecrets: + - name: global-cred + + podSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + +image: + pullSecrets: + - name: local-cred diff --git a/charts/mayastor/charts/alloy/ci/global-image-registry-values.yaml b/charts/mayastor/charts/alloy/ci/global-image-registry-values.yaml new file mode 100644 index 0000000..f4c2d30 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/global-image-registry-values.yaml @@ -0,0 +1,11 @@ +# Test rendering of the chart with the global image registry explicitly set to another value. +global: + image: + registry: quay.io + +image: + registry: docker.com # Invalid value by default + +configReloader: + image: + registry: docker.com diff --git a/charts/mayastor/charts/alloy/ci/host-alias-values.yaml b/charts/mayastor/charts/alloy/ci/host-alias-values.yaml new file mode 100644 index 0000000..1b7f5a9 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/host-alias-values.yaml @@ -0,0 +1,5 @@ +alloy: + hostAliases: + - ip: "20.21.22.23" + hostnames: + - "grafana.company.net" diff --git a/charts/mayastor/charts/alloy/ci/initcontainers-values.yaml b/charts/mayastor/charts/alloy/ci/initcontainers-values.yaml new file mode 100644 index 0000000..4c74c93 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/initcontainers-values.yaml @@ -0,0 +1,29 @@ +controller: + initContainers: + - name: geo-ip + image: ghcr.io/maxmind/geoipupdate:v6.0 + volumeMounts: + - name: geoip + mountPath: /etc/geoip + volumes: + - name: geoip + emptyDir: {} + env: + - name: GEOIPUPDATE_ACCOUNT_ID + value: "geoipupdate_account_id" + - name: GEOIPUPDATE_LICENSE_KEY + value: "geoipupdate_license_key" + - name: GEOIPUPDATE_EDITION_IDS + value: "GeoLite2-ASN GeoLite2-City GeoLite2-Country" + - name: GEOIPUPDATE_DB_DIR + value: "/etc/geoip" + volumes: + extra: + - name: geoip + mountPath: /etc/geoip + +alloy: + mounts: + extra: + - name: geoip + mountPath: /etc/geoip diff --git a/charts/mayastor/charts/alloy/ci/lifecycle-hooks-values.yaml b/charts/mayastor/charts/alloy/ci/lifecycle-hooks-values.yaml new file mode 100644 index 0000000..97fcfef --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/lifecycle-hooks-values.yaml @@ -0,0 +1,8 @@ +controller: + type: deployment + +alloy: + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "sleep 1"] diff --git a/charts/mayastor/charts/alloy/ci/livinessprobe-values.yaml b/charts/mayastor/charts/alloy/ci/livinessprobe-values.yaml new file mode 100644 index 0000000..8badd2b --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/livinessprobe-values.yaml @@ -0,0 +1,11 @@ +alloy: + livenessProbe: + httpGet: + path: /metrics + port: 12345 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 2 + periodSeconds: 30 + successThreshold: 1 + failureThreshold: 3 diff --git a/charts/mayastor/charts/alloy/ci/local-image-pullsecrets-values.yaml b/charts/mayastor/charts/alloy/ci/local-image-pullsecrets-values.yaml new file mode 100644 index 0000000..a7a800f --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/local-image-pullsecrets-values.yaml @@ -0,0 +1,4 @@ +# Test rendering of the chart with the image pull secret explicitly set. +image: + pullSecrets: + - name: local-cred diff --git a/charts/mayastor/charts/alloy/ci/local-image-registry-values.yaml b/charts/mayastor/charts/alloy/ci/local-image-registry-values.yaml new file mode 100644 index 0000000..79fbc67 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/local-image-registry-values.yaml @@ -0,0 +1,7 @@ +# Test rendering of the chart with the individual image registries explicitly set to another value. +image: + registry: quay.io + +configReloader: + image: + registry: quay.io diff --git a/charts/mayastor/charts/alloy/ci/nodeselectors-and-tolerations-values.yaml b/charts/mayastor/charts/alloy/ci/nodeselectors-and-tolerations-values.yaml new file mode 100644 index 0000000..812c271 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/nodeselectors-and-tolerations-values.yaml @@ -0,0 +1,11 @@ +controller: + nodeSelector: + key1: "value1" + tolerations: + - key: "key1" + operator: "Equal" + value: "value1" + effect: "NoSchedule" + - key: "key2" + operator: "Exists" + effect: "NoSchedule" diff --git a/charts/mayastor/charts/alloy/ci/nonroot-values.yaml b/charts/mayastor/charts/alloy/ci/nonroot-values.yaml new file mode 100644 index 0000000..34714be --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/nonroot-values.yaml @@ -0,0 +1,7 @@ +global: + podSecurityContext: + fsGroup: 473 +alloy: + securityContext: + runAsUser: 473 + runAsGroup: 473 diff --git a/charts/mayastor/charts/alloy/ci/pod_annotations-values.yaml b/charts/mayastor/charts/alloy/ci/pod_annotations-values.yaml new file mode 100644 index 0000000..6af944e --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/pod_annotations-values.yaml @@ -0,0 +1,4 @@ +# Test correct rendering of the pod annotations +controller: + podAnnotations: + testAnnotationKey: testAnnotationValue diff --git a/charts/mayastor/charts/alloy/ci/sidecars-values.yaml b/charts/mayastor/charts/alloy/ci/sidecars-values.yaml new file mode 100644 index 0000000..763c546 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/sidecars-values.yaml @@ -0,0 +1,29 @@ +controller: + extraContainers: + - name: geo-ip + image: ghcr.io/maxmind/geoipupdate:v6.0 + volumeMounts: + - name: geoip + mountPath: /etc/geoip + volumes: + - name: geoip + emptyDir: {} + env: + - name: GEOIPUPDATE_ACCOUNT_ID + value: "geoipupdate_account_id" + - name: GEOIPUPDATE_LICENSE_KEY + value: "geoipupdate_license_key" + - name: GEOIPUPDATE_EDITION_IDS + value: "GeoLite2-ASN GeoLite2-City GeoLite2-Country" + - name: GEOIPUPDATE_DB_DIR + value: "/etc/geoip" + volumes: + extra: + - name: geoip + mountPath: /etc/geoip + +alloy: + mounts: + extra: + - name: geoip + mountPath: /etc/geoip diff --git a/charts/mayastor/charts/alloy/ci/termination-grace-period-values.yaml b/charts/mayastor/charts/alloy/ci/termination-grace-period-values.yaml new file mode 100644 index 0000000..4ff8b98 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/termination-grace-period-values.yaml @@ -0,0 +1,3 @@ +controller: + type: deployment + terminationGracePeriodSeconds: 20 diff --git a/charts/mayastor/charts/alloy/ci/topologyspreadconstraints-values.yaml b/charts/mayastor/charts/alloy/ci/topologyspreadconstraints-values.yaml new file mode 100644 index 0000000..9b98df4 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/topologyspreadconstraints-values.yaml @@ -0,0 +1,10 @@ +controller: + type: deployment + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: alloy + app.kubernetes.io/instance: alloy diff --git a/charts/mayastor/charts/alloy/ci/with-digests-values.yaml b/charts/mayastor/charts/alloy/ci/with-digests-values.yaml new file mode 100644 index 0000000..d742dd2 --- /dev/null +++ b/charts/mayastor/charts/alloy/ci/with-digests-values.yaml @@ -0,0 +1,10 @@ +image: + registry: "docker.io" + repository: "grafana/agent" + digest: "sha256:82575a7be3e4770e53f620298e58bcc4cdb0fd0338e01c4b206cae9e3ca46ebf" + +configReloader: + image: + registry: "docker.io" + repository: "jimmidyson/configmap-reload" + digest: "sha256:5af9d3041d12a3e63f115125f89b66d2ba981fe82e64302ac370c5496055059c" diff --git a/charts/mayastor/charts/alloy/config/example.alloy b/charts/mayastor/charts/alloy/config/example.alloy new file mode 100644 index 0000000..e356547 --- /dev/null +++ b/charts/mayastor/charts/alloy/config/example.alloy @@ -0,0 +1,28 @@ +logging { + level = "info" + format = "logfmt" +} + +discovery.kubernetes "pods" { + role = "pod" +} + +discovery.kubernetes "nodes" { + role = "node" +} + +discovery.kubernetes "services" { + role = "service" +} + +discovery.kubernetes "endpoints" { + role = "endpoints" +} + +discovery.kubernetes "endpointslices" { + role = "endpointslice" +} + +discovery.kubernetes "ingresses" { + role = "ingress" +} diff --git a/charts/mayastor/charts/alloy/templates/NOTES.txt b/charts/mayastor/charts/alloy/templates/NOTES.txt new file mode 100644 index 0000000..2c3176b --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/NOTES.txt @@ -0,0 +1 @@ +Welcome to Grafana Alloy! diff --git a/charts/mayastor/charts/alloy/templates/_config.tpl b/charts/mayastor/charts/alloy/templates/_config.tpl new file mode 100644 index 0000000..54b8225 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/_config.tpl @@ -0,0 +1,25 @@ +{{/* +Retrieve configMap name from the name of the chart or the ConfigMap the user +specified. +*/}} +{{- define "alloy.config-map.name" -}} +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if $values.configMap.name -}} +{{- $values.configMap.name }} +{{- else -}} +{{- include "alloy.fullname" . }} +{{- end }} +{{- end }} + +{{/* +The name of the config file is the default or the key the user specified in the +ConfigMap. +*/}} +{{- define "alloy.config-map.key" -}} +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if $values.configMap.key -}} +{{- $values.configMap.key }} +{{- else -}} +config.alloy +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/_helpers.tpl b/charts/mayastor/charts/alloy/templates/_helpers.tpl new file mode 100644 index 0000000..2695f9c --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/_helpers.tpl @@ -0,0 +1,162 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "alloy.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +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 "alloy.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "alloy.chart" -}} +{{- if index .Values "$chart_tests" }} +{{- printf "%s" .Chart.Name | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "alloy.namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "alloy.labels" -}} +helm.sh/chart: {{ include "alloy.chart" . }} +{{ include "alloy.selectorLabels" . }} +{{- if index .Values "$chart_tests" }} +app.kubernetes.io/version: "vX.Y.Z" +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- else -}} +{{/* substr trims delimeter prefix char from alloy.imageId output + e.g. ':' for tags and '@' for digests. + For digests, we crop the string to a 7-char (short) sha. */}} +app.kubernetes.io/version: {{ (include "alloy.imageId" .) | trunc 15 | trimPrefix "@sha256" | trimPrefix ":" | quote }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/part-of: alloy +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "alloy.selectorLabels" -}} +app.kubernetes.io/name: {{ include "alloy.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "alloy.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "alloy.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Calculate name of image ID to use for "alloy. +*/}} +{{- define "alloy.imageId" -}} +{{- if .Values.image.digest }} +{{- $digest := .Values.image.digest }} +{{- if not (hasPrefix "sha256:" $digest) }} +{{- $digest = printf "sha256:%s" $digest }} +{{- end }} +{{- printf "@%s" $digest }} +{{- else if .Values.image.tag }} +{{- printf ":%s" .Values.image.tag }} +{{- else }} +{{- printf ":%s" .Chart.AppVersion }} +{{- end }} +{{- end }} + +{{/* +Calculate name of image ID to use for "config-reloader". +*/}} +{{- define "config-reloader.imageId" -}} +{{- if .Values.configReloader.image.digest }} +{{- $digest := .Values.configReloader.image.digest }} +{{- if not (hasPrefix "sha256:" $digest) }} +{{- $digest = printf "sha256:%s" $digest }} +{{- end }} +{{- printf "@%s" $digest }} +{{- else if .Values.configReloader.image.tag }} +{{- printf ":%s" .Values.configReloader.image.tag }} +{{- else }} +{{- printf ":%s" "v0.8.0" }} +{{- end }} +{{- end }} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "alloy.ingress.apiVersion" -}} +{{- if and ($.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19-0" .Capabilities.KubeVersion.Version) }} +{{- print "networking.k8s.io/v1" }} +{{- else if $.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} +{{- print "networking.k8s.io/v1beta1" }} +{{- else }} +{{- print "extensions/v1beta1" }} +{{- end }} +{{- end }} + +{{/* +Return if ingress is stable. +*/}} +{{- define "alloy.ingress.isStable" -}} +{{- eq (include "alloy.ingress.apiVersion" .) "networking.k8s.io/v1" }} +{{- end }} + +{{/* +Return if ingress supports ingressClassName. +*/}} +{{- define "alloy.ingress.supportsIngressClassName" -}} +{{- or (eq (include "alloy.ingress.isStable" .) "true") (and (eq (include "alloy.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) }} +{{- end }} +{{/* +Return if ingress supports pathType. +*/}} +{{- define "alloy.ingress.supportsPathType" -}} +{{- or (eq (include "alloy.ingress.isStable" .) "true") (and (eq (include "alloy.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) }} +{{- end }} + +{{/* +Return the appropriate apiVersion for PodDisruptionBudget. +*/}} +{{- define "alloy.controller.pdb.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "policy/v1") (semverCompare ">=1.21-0" .Capabilities.KubeVersion.Version) -}} + {{- print "policy/v1" -}} + {{- else -}} + {{- print "policy/v1beta1" -}} + {{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/alloy/templates/cluster_service.yaml b/charts/mayastor/charts/alloy/templates/cluster_service.yaml new file mode 100644 index 0000000..090ad52 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/cluster_service.yaml @@ -0,0 +1,38 @@ +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if $values.clustering.enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "alloy.fullname" . }}-cluster + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: networking +spec: + type: ClusterIP + clusterIP: 'None' + publishNotReadyAddresses: true + selector: + {{- include "alloy.selectorLabels" . | nindent 4 }} + ports: + # Do not include the -metrics suffix in the port name, otherwise metrics + # can be double-collected with the non-headless Service if it's also + # enabled. + # + # This service should only be used for clustering, and not metric + # collection. + - name: {{ $values.clustering.portName }} + port: {{ $values.listenPort }} + targetPort: {{ $values.listenPort }} + protocol: "TCP" + {{- range $portMap := $values.extraPorts }} + - name: {{ $portMap.name }} + port: {{ $portMap.port }} + targetPort: {{ $portMap.targetPort }} + protocol: {{ coalesce $portMap.protocol "TCP" }} + {{- if not (empty $portMap.appProtocol) }} + # Useful for OpenShift clusters that want to expose Alloy ports externally + appProtocol: {{ $portMap.appProtocol }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/configmap.yaml b/charts/mayastor/charts/alloy/templates/configmap.yaml new file mode 100644 index 0000000..1acadef --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/configmap.yaml @@ -0,0 +1,17 @@ +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if $values.configMap.create }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "alloy.config-map.name" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: config +data: + {{- if $values.configMap.content }} + config.alloy: |- {{- (tpl $values.configMap.content .) | nindent 4 }} + {{- else }} + config.alloy: |- {{- .Files.Get "config/example.alloy" | trim | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/containers/_agent.yaml b/charts/mayastor/charts/alloy/templates/containers/_agent.yaml new file mode 100644 index 0000000..89968b7 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/containers/_agent.yaml @@ -0,0 +1,92 @@ +{{- define "alloy.container" -}} +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +- name: alloy + image: {{ .Values.global.image.registry | default .Values.image.registry }}/{{ .Values.image.repository }}{{ include "alloy.imageId" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - run + - /etc/alloy/{{ include "alloy.config-map.key" . }} + - --storage.path={{ $values.storagePath }} + - --server.http.listen-addr={{ $values.listenAddr }}:{{ $values.listenPort }} + - --server.http.ui-path-prefix={{ $values.uiPathPrefix }} + {{- if not $values.enableReporting }} + - --disable-reporting + {{- end}} + {{- if $values.clustering.enabled }} + - --cluster.enabled=true + - --cluster.join-addresses={{ include "alloy.fullname" . }}-cluster + {{- if $values.clustering.name }} + - --cluster.name={{ $values.clustering.name }} + {{- end}} + {{- end}} + {{- if $values.stabilityLevel }} + - --stability.level={{ $values.stabilityLevel }} + {{- end }} + {{- range $values.extraArgs }} + - {{ . }} + {{- end}} + env: + - name: ALLOY_DEPLOY_MODE + value: "helm" + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{- range $values.extraEnv }} + - {{- toYaml . | nindent 6 }} + {{- end }} + {{- if $values.envFrom }} + envFrom: + {{- toYaml $values.envFrom | nindent 4 }} + {{- end }} + ports: + - containerPort: {{ $values.listenPort }} + name: http-metrics + {{- range $portMap := $values.extraPorts }} + - containerPort: {{ $portMap.targetPort }} + {{- if $portMap.hostPort }} + hostPort: {{ $portMap.hostPort }} + {{- end}} + name: {{ $portMap.name }} + protocol: {{ coalesce $portMap.protocol "TCP" }} + {{- end }} + readinessProbe: + httpGet: + path: /-/ready + port: {{ $values.listenPort }} + scheme: {{ $values.listenScheme }} + initialDelaySeconds: 10 + timeoutSeconds: 1 + {{- with $values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $values.resources }} + resources: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $values.lifecycle }} + lifecycle: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $values.securityContext }} + securityContext: + {{- toYaml . | nindent 4 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/alloy + {{- if $values.mounts.varlog }} + - name: varlog + mountPath: /var/log + readOnly: true + {{- end }} + {{- if $values.mounts.dockercontainers }} + - name: dockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + {{- end }} + {{- range $values.mounts.extra }} + - {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/containers/_watch.yaml b/charts/mayastor/charts/alloy/templates/containers/_watch.yaml new file mode 100644 index 0000000..d17dc31 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/containers/_watch.yaml @@ -0,0 +1,26 @@ +{{- define "alloy.watch-container" -}} +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if .Values.configReloader.enabled -}} +- name: config-reloader + image: {{ .Values.global.image.registry | default .Values.configReloader.image.registry }}/{{ .Values.configReloader.image.repository }}{{ include "config-reloader.imageId" . }} + {{- if .Values.configReloader.customArgs }} + args: + {{- toYaml .Values.configReloader.customArgs | nindent 4 }} + {{- else }} + args: + - --watched-dir=/etc/alloy + - --reload-url=http://localhost:{{ $values.listenPort }}/-/reload + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/alloy + {{- with .Values.configReloader.resources }} + resources: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.configReloader.securityContext }} + securityContext: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- end -}} diff --git a/charts/mayastor/charts/alloy/templates/controllers/_pod.yaml b/charts/mayastor/charts/alloy/templates/controllers/_pod.yaml new file mode 100644 index 0000000..453bdfd --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/controllers/_pod.yaml @@ -0,0 +1,93 @@ +{{- define "alloy.pod-template" -}} +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +metadata: + annotations: + kubectl.kubernetes.io/default-container: alloy + {{- if and $values.configMap.create $values.configMap.content }} + checksum/config: {{ (tpl $values.configMap.content .) | sha256sum | trunc 63 }} + {{- end }} + {{- with .Values.controller.podAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "alloy.selectorLabels" . | nindent 4 }} + {{- with .Values.controller.podLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.global.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 4 }} + {{- end }} + serviceAccountName: {{ include "alloy.serviceAccountName" . }} + {{- if or .Values.global.image.pullSecrets .Values.image.pullSecrets }} + imagePullSecrets: + {{- if .Values.global.image.pullSecrets }} + {{- toYaml .Values.global.image.pullSecrets | nindent 4 }} + {{- else }} + {{- toYaml .Values.image.pullSecrets | nindent 4 }} + {{- end }} + {{- end }} + {{- if .Values.controller.initContainers }} + initContainers: + {{- with .Values.controller.initContainers }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + containers: + {{- include "alloy.container" . | nindent 4 }} + {{- include "alloy.watch-container" . | nindent 4 }} + {{- with .Values.controller.extraContainers }} + {{- toYaml . | nindent 4 }} + {{- end}} + {{- if .Values.controller.priorityClassName }} + priorityClassName: {{ .Values.controller.priorityClassName }} + {{- end }} + {{- if .Values.controller.hostNetwork }} + hostNetwork: {{ .Values.controller.hostNetwork }} + {{- end }} + {{- if .Values.controller.hostPID }} + hostPID: {{ .Values.controller.hostPID }} + {{- end }} + dnsPolicy: {{ .Values.controller.dnsPolicy }} + {{- with .Values.controller.affinity }} + affinity: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.controller.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds | int }} + {{- end }} + {{- with .Values.controller.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.controller.tolerations }} + tolerations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.controller.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 4 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "alloy.config-map.name" . }} + {{- if $values.mounts.varlog }} + - name: varlog + hostPath: + path: /var/log + {{- end }} + {{- if $values.mounts.dockercontainers }} + - name: dockercontainers + hostPath: + path: /var/lib/docker/containers + {{- end }} + {{- if .Values.controller.volumes.extra }} + {{- toYaml .Values.controller.volumes.extra | nindent 4 }} + {{- end }} + {{- if $values.hostAliases }} + hostAliases: + {{- toYaml $values.hostAliases | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/controllers/daemonset.yaml b/charts/mayastor/charts/alloy/templates/controllers/daemonset.yaml new file mode 100644 index 0000000..b692995 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/controllers/daemonset.yaml @@ -0,0 +1,26 @@ +{{- if eq .Values.controller.type "daemonset" }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + {{- with .Values.controller.extraAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if ge (int .Capabilities.KubeVersion.Minor) 22 }} + minReadySeconds: 10 + {{- end }} + selector: + matchLabels: + {{- include "alloy.selectorLabels" . | nindent 6 }} + template: + {{- include "alloy.pod-template" . | nindent 4 }} + {{- with .Values.controller.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/controllers/deployment.yaml b/charts/mayastor/charts/alloy/templates/controllers/deployment.yaml new file mode 100644 index 0000000..07d6912 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/controllers/deployment.yaml @@ -0,0 +1,29 @@ +{{- if eq .Values.controller.type "deployment" }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + {{- with .Values.controller.extraAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if not .Values.controller.autoscaling.enabled }} + replicas: {{ .Values.controller.replicas }} + {{- end }} + {{- if ge (int .Capabilities.KubeVersion.Minor) 22 }} + minReadySeconds: 10 + {{- end }} + selector: + matchLabels: + {{- include "alloy.selectorLabels" . | nindent 6 }} + template: + {{- include "alloy.pod-template" . | nindent 4 }} + {{- with .Values.controller.updateStrategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/controllers/statefulset.yaml b/charts/mayastor/charts/alloy/templates/controllers/statefulset.yaml new file mode 100644 index 0000000..a290834 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/controllers/statefulset.yaml @@ -0,0 +1,51 @@ +{{- if eq .Values.controller.type "statefulset" }} +{{- if .Values.enableStatefulSetAutoDeletePVC }} +{{- fail "Value 'enableStatefulSetAutoDeletePVC' should be nested inside 'controller' options." }} +{{- end }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + {{- with .Values.controller.extraAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if not .Values.controller.autoscaling.enabled }} + replicas: {{ .Values.controller.replicas }} + {{- end }} + {{- if .Values.controller.parallelRollout }} + podManagementPolicy: Parallel + {{- end }} + {{- if ge (int .Capabilities.KubeVersion.Minor) 22 }} + minReadySeconds: 10 + {{- end }} + serviceName: {{ include "alloy.fullname" . }} + selector: + matchLabels: + {{- include "alloy.selectorLabels" . | nindent 6 }} + template: + {{- include "alloy.pod-template" . | nindent 4 }} + {{- with .Values.controller.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.controller.volumeClaimTemplates }} + volumeClaimTemplates: + {{- range . }} + - {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} + {{- if and (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) (.Values.controller.enableStatefulSetAutoDeletePVC) }} + {{- /* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/extra-manifests.yaml b/charts/mayastor/charts/alloy/templates/extra-manifests.yaml new file mode 100644 index 0000000..a9bb3b6 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/charts/mayastor/charts/alloy/templates/hpa.yaml b/charts/mayastor/charts/alloy/templates/hpa.yaml new file mode 100644 index 0000000..a2286c7 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/hpa.yaml @@ -0,0 +1,83 @@ +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if and (or (eq .Values.controller.type "deployment") (eq .Values.controller.type "statefulset" )) (or .Values.controller.autoscaling.horizontal.enabled .Values.controller.autoscaling.enabled) }} +{{ $autoscaling := .Values.controller.autoscaling }} +{{- if .Values.controller.autoscaling.horizontal.enabled }} +{{- $autoscaling = .Values.controller.autoscaling.horizontal }} +{{- end }} +{{- if (not (empty $autoscaling.targetMemoryUtilizationPercentage)) }} + {{- $_ := $values.resources.requests | required ".Values.alloy.resources.requests is required when using autoscaling." -}} + {{- $_ := $values.resources.requests.memory | required ".Values.alloy.resources.requests.memory is required when using autoscaling based on memory utilization." -}} + {{- $_ := .Values.configReloader.resources.requests | required ".Values.configReloader.resources.requests is required when using autoscaling." -}} + {{- $_ := .Values.configReloader.resources.requests.memory | required ".Values.configReloader.resources.requests.memory is required when using autoscaling based on memory utilization." -}} +{{- end}} +{{- if (not (empty $autoscaling.targetCPUUtilizationPercentage)) }} + {{- $_ := $values.resources.requests | required ".Values.alloy.resources.requests is required when using autoscaling." -}} + {{- $_ := $values.resources.requests.cpu | required ".Values.alloy.resources.requests.cpu is required when using autoscaling based on cpu utilization." -}} + {{- $_ := .Values.configReloader.resources.requests | required ".Values.configReloader.resources.requests is required when using autoscaling." -}} + {{- $_ := .Values.configReloader.resources.requests.cpu | required ".Values.configReloader.resources.requests.cpu is required when using autoscaling based on cpu utilization." -}} +{{- end}} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: availability +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: {{ .Values.controller.type }} + name: {{ include "alloy.fullname" . }} + {{- with $autoscaling }} + minReplicas: {{ .minReplicas }} + maxReplicas: {{ .maxReplicas }} + behavior: + {{- with .scaleDown }} + scaleDown: + {{- if .policies }} + policies: + {{- range .policies }} + - type: {{ .type }} + value: {{ .value }} + periodSeconds: {{ .periodSeconds }} + {{- end }} + selectPolicy: {{ .selectPolicy }} + {{- end }} + stabilizationWindowSeconds: {{ .stabilizationWindowSeconds }} + {{- end }} + {{- with .scaleUp }} + scaleUp: + {{- if .policies }} + policies: + {{- range .policies }} + - type: {{ .type }} + value: {{ .value }} + periodSeconds: {{ .periodSeconds }} + {{- end }} + selectPolicy: {{ .selectPolicy }} + {{- end }} + stabilizationWindowSeconds: {{ .stabilizationWindowSeconds }} + {{- end }} + metrics: + # Changing the order of the metrics will cause ArgoCD to go into a sync loop + # memory needs to be first. + # More info in: https://github.com/argoproj/argo-cd/issues/1079 + {{- with .targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} + {{- with .targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/ingress.yaml b/charts/mayastor/charts/alloy/templates/ingress.yaml new file mode 100644 index 0000000..51a6e57 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/ingress.yaml @@ -0,0 +1,79 @@ +{{- if .Values.ingress.enabled -}} +{{- $ingressApiIsStable := eq (include "alloy.ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "alloy.ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "alloy.ingress.supportsPathType" .) "true" -}} +{{- $fullName := include "alloy.fullname" . -}} +{{- $servicePort := .Values.ingress.faroPort -}} +{{- $ingressPath := .Values.ingress.path -}} +{{- $ingressPathType := .Values.ingress.pathType -}} +{{- $extraPaths := .Values.ingress.extraPaths -}} +apiVersion: {{ include "alloy.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: networking + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingress.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ tpl $value $ | quote }} + {{- end }} + {{- end }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end -}} + {{- with .Values.ingress.tls }} + tls: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + rules: + {{- if .Values.ingress.hosts }} + {{- range .Values.ingress.hosts }} + - host: {{ tpl . $ }} + http: + paths: + {{- with $extraPaths }} + {{- toYaml . | nindent 10 }} + {{- end }} + - path: {{ $ingressPath }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end }} + {{- else }} + - http: + paths: + - backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- with $ingressPath }} + path: {{ . }} + {{- end }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + {{- end -}} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/pdb.yaml b/charts/mayastor/charts/alloy/templates/pdb.yaml new file mode 100644 index 0000000..87b9db4 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/pdb.yaml @@ -0,0 +1,31 @@ +{{- if .Values.controller.podDisruptionBudget.enabled }} +{{- if eq .Values.controller.type "daemonset" }} +{{- fail "PDBs (Pod Disruption Budgets) are not intended for DaemonSets. Please use a different controller type." }} +{{- end }} + +{{- if and .Values.controller.podDisruptionBudget.minAvailable .Values.controller.podDisruptionBudget.maxUnavailable }} +{{- fail "Only one of minAvailable or maxUnavailable should be defined for PodDisruptionBudget" }} +{{- end }} + +{{- if not (or .Values.controller.podDisruptionBudget.minAvailable .Values.controller.podDisruptionBudget.maxUnavailable) }} +{{- fail "Either minAvailable or maxUnavailable must be defined for PodDisruptionBudget" }} +{{- end }} + +apiVersion: {{ include "alloy.controller.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "alloy.selectorLabels" . | nindent 6 }} + {{- if .Values.controller.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.controller.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.controller.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.controller.podDisruptionBudget.maxUnavailable }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/rbac.yaml b/charts/mayastor/charts/alloy/templates/rbac.yaml new file mode 100644 index 0000000..38ccb0f --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/rbac.yaml @@ -0,0 +1,112 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "alloy.fullname" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: rbac +rules: + # Rules which allow discovery.kubernetes to function. + - apiGroups: + - "" + - "discovery.k8s.io" + - "networking.k8s.io" + resources: + - endpoints + - endpointslices + - ingresses + - nodes + - nodes/proxy + - nodes/metrics + - pods + - services + verbs: + - get + - list + - watch + # Rules which allow loki.source.kubernetes and loki.source.podlogs to work. + - apiGroups: + - "" + resources: + - pods + - pods/log + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - "monitoring.grafana.com" + resources: + - podlogs + verbs: + - get + - list + - watch + # Rules which allow mimir.rules.kubernetes to work. + - apiGroups: ["monitoring.coreos.com"] + resources: + - prometheusrules + verbs: + - get + - list + - watch + - nonResourceURLs: + - /metrics + verbs: + - get + # Rules for prometheus.kubernetes.* + - apiGroups: ["monitoring.coreos.com"] + resources: + - podmonitors + - servicemonitors + - probes + - scrapeconfigs + verbs: + - get + - list + - watch + # Rules which allow eventhandler to work. + - apiGroups: + - "" + resources: + - events + verbs: + - get + - list + - watch + # needed for remote.kubernetes.* + - apiGroups: [""] + resources: + - "configmaps" + - "secrets" + verbs: + - get + - list + - watch + # needed for otelcol.processor.k8sattributes + - apiGroups: ["apps"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] + - apiGroups: ["extensions"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "alloy.fullname" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: rbac +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "alloy.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "alloy.serviceAccountName" . }} + namespace: {{ include "alloy.namespace" . }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/service.yaml b/charts/mayastor/charts/alloy/templates/service.yaml new file mode 100644 index 0000000..53f79b3 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/service.yaml @@ -0,0 +1,43 @@ +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if .Values.service.enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: networking + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- if .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + selector: + {{- include "alloy.selectorLabels" . | nindent 4 }} + {{- if semverCompare ">=1.26-0" .Capabilities.KubeVersion.Version }} + internalTrafficPolicy: {{.Values.service.internalTrafficPolicy}} + {{- end }} + ports: + - name: http-metrics + {{- if eq .Values.service.type "NodePort" }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + port: {{ $values.listenPort }} + targetPort: {{ $values.listenPort }} + protocol: "TCP" +{{- range $portMap := $values.extraPorts }} + - name: {{ $portMap.name }} + port: {{ $portMap.port }} + targetPort: {{ $portMap.targetPort }} + protocol: {{ coalesce $portMap.protocol "TCP" }} + {{- if not (empty $portMap.appProtocol) }} + # Useful for OpenShift clusters that want to expose Alloy ports externally + appProtocol: {{ $portMap.appProtocol }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/serviceaccount.yaml b/charts/mayastor/charts/alloy/templates/serviceaccount.yaml new file mode 100644 index 0000000..55a6e91 --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "alloy.serviceAccountName" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: rbac + {{- with .Values.serviceAccount.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/servicemonitor.yaml b/charts/mayastor/charts/alloy/templates/servicemonitor.yaml new file mode 100644 index 0000000..382b38a --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/servicemonitor.yaml @@ -0,0 +1,37 @@ +{{- $values := (mustMergeOverwrite .Values.alloy (or .Values.agent dict)) -}} +{{- if and .Values.service.enabled .Values.serviceMonitor.enabled -}} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "alloy.fullname" . }} + namespace: {{ include "alloy.namespace" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: metrics + {{- with .Values.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: http-metrics + scheme: {{ $values.listenScheme | lower }} + honorLabels: true + {{- if .Values.serviceMonitor.interval }} + interval: {{ .Values.serviceMonitor.interval }} + {{- end }} + {{- if .Values.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{ tpl (toYaml .Values.serviceMonitor.metricRelabelings | nindent 6) . }} + {{- end }} + {{- if .Values.serviceMonitor.relabelings }} + relabelings: + {{ tpl (toYaml .Values.serviceMonitor.relabelings | nindent 6) . }} + {{- end }} + {{- with .Values.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 6 }} + {{- end }} + selector: + matchLabels: + {{- include "alloy.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/templates/vpa.yaml b/charts/mayastor/charts/alloy/templates/vpa.yaml new file mode 100644 index 0000000..09877ee --- /dev/null +++ b/charts/mayastor/charts/alloy/templates/vpa.yaml @@ -0,0 +1,41 @@ +{{- if .Capabilities.APIVersions.Has "autoscaling.k8s.io/v1" -}} +{{- if .Values.controller.autoscaling.vertical.enabled -}} +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: {{ include "alloy.fullname" . }} + labels: + {{- include "alloy.labels" . | nindent 4 }} + app.kubernetes.io/component: availability +spec: + {{- with .Values.controller.autoscaling.vertical }} + {{- with .recommenders }} + recommenders: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .resourcePolicy }} + resourcePolicy: + {{- with .containerPolicies }} + containerPolicies: + {{- range . }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + {{- end }} + {{- with .updatePolicy }} + updatePolicy: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + targetRef: + apiVersion: apps/v1 + {{- if eq .Values.controller.type "deployment" }} + kind: Deployment + {{- else if eq .Values.controller.type "statefulset" }} + kind: StatefulSet + {{- else }} + kind: DaemonSet + {{- end }} + name: {{ include "alloy.fullname" . }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/alloy/values.yaml b/charts/mayastor/charts/alloy/values.yaml new file mode 100644 index 0000000..8820a47 --- /dev/null +++ b/charts/mayastor/charts/alloy/values.yaml @@ -0,0 +1,463 @@ +# -- Overrides the chart's name. Used to change the infix in the resource names. +nameOverride: null + +# -- Overrides the chart's namespace. +namespaceOverride: null + +# -- Overrides the chart's computed fullname. Used to change the full prefix of +# resource names. +fullnameOverride: null + +## Global properties for image pulling override the values defined under `image.registry` and `configReloader.image.registry`. +## If you want to override only one image registry, use the specific fields but if you want to override them all, use `global.image.registry` +global: + image: + # -- Global image registry to use if it needs to be overridden for some specific use cases (e.g local registries, custom images, ...) + registry: "" + + # -- Optional set of global image pull secrets. + pullSecrets: [] + + # -- Security context to apply to the Grafana Alloy pod. + podSecurityContext: {} + +crds: + # -- Whether to install CRDs for monitoring. + create: true + +## Various Alloy settings. For backwards compatibility with the grafana-agent +## chart, this field may also be called "agent". Naming this field "agent" is +## deprecated and will be removed in a future release. +alloy: + configMap: + # -- Create a new ConfigMap for the config file. + create: true + # -- Content to assign to the new ConfigMap. This is passed into `tpl` allowing for templating from values. + content: '' + + # -- Name of existing ConfigMap to use. Used when create is false. + name: null + # -- Key in ConfigMap to get config from. + key: null + + clustering: + # -- Deploy Alloy in a cluster to allow for load distribution. + enabled: false + + # -- Name for the Alloy cluster. Used for differentiating between clusters. + name: "" + + # -- Name for the port used for clustering, useful if running inside an Istio Mesh + portName: http + + # -- Minimum stability level of components and behavior to enable. Must be + # one of "experimental", "public-preview", or "generally-available". + stabilityLevel: "generally-available" + + # -- Path to where Grafana Alloy stores data (for example, the Write-Ahead Log). + # By default, data is lost between reboots. + storagePath: /tmp/alloy + + # -- Address to listen for traffic on. 0.0.0.0 exposes the UI to other + # containers. + listenAddr: 0.0.0.0 + + # -- Port to listen for traffic on. + listenPort: 12345 + + # -- Scheme is needed for readiness probes. If enabling tls in your configs, set to "HTTPS" + listenScheme: HTTP + + # -- Base path where the UI is exposed. + uiPathPrefix: / + + # -- Enables sending Grafana Labs anonymous usage stats to help improve Grafana + # Alloy. + enableReporting: true + + # -- Extra environment variables to pass to the Alloy container. + extraEnv: [] + + # -- Maps all the keys on a ConfigMap or Secret as environment variables. https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#envfromsource-v1-core + envFrom: [] + + # -- Extra args to pass to `alloy run`: https://grafana.com/docs/alloy/latest/reference/cli/run/ + extraArgs: [] + + # -- Extra ports to expose on the Alloy container. + extraPorts: [] + # - name: "faro" + # port: 12347 + # targetPort: 12347 + # protocol: "TCP" + # appProtocol: "h2c" + + # -- Host aliases to add to the Alloy container. + hostAliases: [] + # - ip: "20.21.22.23" + # hostnames: + # - "company.grafana.net" + + mounts: + # -- Mount /var/log from the host into the container for log collection. + varlog: false + # -- Mount /var/lib/docker/containers from the host into the container for log + # collection. + dockercontainers: false + + # -- Extra volume mounts to add into the Grafana Alloy container. Does not + # affect the watch container. + extra: [] + + # -- Security context to apply to the Grafana Alloy container. + securityContext: {} + + # -- Resource requests and limits to apply to the Grafana Alloy container. + resources: {} + + # -- Set lifecycle hooks for the Grafana Alloy container. + lifecycle: {} + # preStop: + # exec: + # command: + # - /bin/sleep + # - "10" + + # -- Set livenessProbe for the Grafana Alloy container. + livenessProbe: {} + +image: + # -- Grafana Alloy image registry (defaults to docker.io) + registry: "docker.io" + # -- Grafana Alloy image repository. + repository: grafana/alloy + # -- (string) Grafana Alloy image tag. When empty, the Chart's appVersion is + # used. + tag: null + # -- Grafana Alloy image's SHA256 digest (either in format "sha256:XYZ" or "XYZ"). When set, will override `image.tag`. + digest: null + # -- Grafana Alloy image pull policy. + pullPolicy: IfNotPresent + # -- Optional set of image pull secrets. + pullSecrets: [] + +rbac: + # -- Whether to create RBAC resources for Alloy. + create: true + +serviceAccount: + # -- Whether to create a service account for the Grafana Alloy deployment. + create: true + # -- Additional labels to add to the created service account. + additionalLabels: {} + # -- Annotations to add to the created service account. + annotations: {} + # -- The name of the existing service account to use when + # serviceAccount.create is false. + name: null + # Whether the Alloy pod should automatically mount the service account token. + automountServiceAccountToken: true + +# Options for the extra controller used for config reloading. +configReloader: + # -- Enables automatically reloading when the Alloy config changes. + enabled: true + image: + # -- Config reloader image registry (defaults to docker.io) + registry: "quay.io" + # -- Repository to get config reloader image from. + repository: prometheus-operator/prometheus-config-reloader + # -- Tag of image to use for config reloading. + tag: v0.81.0 + # -- SHA256 digest of image to use for config reloading (either in format "sha256:XYZ" or "XYZ"). When set, will override `configReloader.image.tag` + digest: "" + # -- Override the args passed to the container. + customArgs: [] + # -- Resource requests and limits to apply to the config reloader container. + resources: + requests: + cpu: "10m" + memory: "50Mi" + # -- Security context to apply to the Grafana configReloader container. + securityContext: {} + +controller: + # -- Type of controller to use for deploying Grafana Alloy in the cluster. + # Must be one of 'daemonset', 'deployment', or 'statefulset'. + type: 'daemonset' + + # -- Number of pods to deploy. Ignored when controller.type is 'daemonset'. + replicas: 1 + + # -- Annotations to add to controller. + extraAnnotations: {} + + # -- Whether to deploy pods in parallel. Only used when controller.type is + # 'statefulset'. + parallelRollout: true + + # -- Configures Pods to use the host network. When set to true, the ports that will be used must be specified. + hostNetwork: false + + # -- Configures Pods to use the host PID namespace. + hostPID: false + + # -- Configures the DNS policy for the pod. https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy + dnsPolicy: ClusterFirst + + # -- Termination grace period in seconds for the Grafana Alloy pods. + # The default value used by Kubernetes if unspecifed is 30 seconds. + terminationGracePeriodSeconds: null + + # -- Update strategy for updating deployed Pods. + updateStrategy: {} + + # -- nodeSelector to apply to Grafana Alloy pods. + nodeSelector: {} + + # -- Tolerations to apply to Grafana Alloy pods. + tolerations: [] + + # -- Topology Spread Constraints to apply to Grafana Alloy pods. + topologySpreadConstraints: [] + + # -- priorityClassName to apply to Grafana Alloy pods. + priorityClassName: '' + + # -- Extra pod annotations to add. + podAnnotations: {} + + # -- Extra pod labels to add. + podLabels: {} + + # -- PodDisruptionBudget configuration. + podDisruptionBudget: + # -- Whether to create a PodDisruptionBudget for the controller. + enabled: false + # -- Minimum number of pods that must be available during a disruption. + # Note: Only one of minAvailable or maxUnavailable should be set. + minAvailable: null + # -- Maximum number of pods that can be unavailable during a disruption. + # Note: Only one of minAvailable or maxUnavailable should be set. + maxUnavailable: null + + # -- Whether to enable automatic deletion of stale PVCs due to a scale down operation, when controller.type is 'statefulset'. + enableStatefulSetAutoDeletePVC: false + + autoscaling: + # -- Creates a HorizontalPodAutoscaler for controller type deployment. + # Deprecated: Please use controller.autoscaling.horizontal instead + enabled: false + # -- The lower limit for the number of replicas to which the autoscaler can scale down. + minReplicas: 1 + # -- The upper limit for the number of replicas to which the autoscaler can scale up. + maxReplicas: 5 + # -- Average CPU utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetCPUUtilizationPercentage` to 0 will disable CPU scaling. + targetCPUUtilizationPercentage: 0 + # -- Average Memory utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetMemoryUtilizationPercentage` to 0 will disable Memory scaling. + targetMemoryUtilizationPercentage: 80 + + scaleDown: + # -- List of policies to determine the scale-down behavior. + policies: [] + # - type: Pods + # value: 4 + # periodSeconds: 60 + # -- Determines which of the provided scaling-down policies to apply if multiple are specified. + selectPolicy: Max + # -- The duration that the autoscaling mechanism should look back on to make decisions about scaling down. + stabilizationWindowSeconds: 300 + + scaleUp: + # -- List of policies to determine the scale-up behavior. + policies: [] + # - type: Pods + # value: 4 + # periodSeconds: 60 + # -- Determines which of the provided scaling-up policies to apply if multiple are specified. + selectPolicy: Max + # -- The duration that the autoscaling mechanism should look back on to make decisions about scaling up. + stabilizationWindowSeconds: 0 + + # -- Configures the Horizontal Pod Autoscaler for the controller. + horizontal: + # -- Enables the Horizontal Pod Autoscaler for the controller. + enabled: false + + # -- The lower limit for the number of replicas to which the autoscaler can scale down. + minReplicas: 1 + # -- The upper limit for the number of replicas to which the autoscaler can scale up. + maxReplicas: 5 + # -- Average CPU utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetCPUUtilizationPercentage` to 0 will disable CPU scaling. + targetCPUUtilizationPercentage: 0 + # -- Average Memory utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetMemoryUtilizationPercentage` to 0 will disable Memory scaling. + targetMemoryUtilizationPercentage: 80 + + scaleDown: + # -- List of policies to determine the scale-down behavior. + policies: [] + # - type: Pods + # value: 4 + # periodSeconds: 60 + # -- Determines which of the provided scaling-down policies to apply if multiple are specified. + selectPolicy: Max + # -- The duration that the autoscaling mechanism should look back on to make decisions about scaling down. + stabilizationWindowSeconds: 300 + + scaleUp: + # -- List of policies to determine the scale-up behavior. + policies: [] + # - type: Pods + # value: 4 + # periodSeconds: 60 + # -- Determines which of the provided scaling-up policies to apply if multiple are specified. + selectPolicy: Max + # -- The duration that the autoscaling mechanism should look back on to make decisions about scaling up. + stabilizationWindowSeconds: 0 + # -- Configures the Vertical Pod Autoscaler for the controller. + vertical: + # -- Enables the Vertical Pod Autoscaler for the controller. + enabled: false + + # -- List of recommenders to use for the Vertical Pod Autoscaler. + # Recommenders are responsible for generating recommendation for the object. + # List should be empty (then the default recommender will generate the recommendation) + # or contain exactly one recommender. + recommenders: [] + # recommenders: + # - name: custom-recommender-performance + + # -- Configures the resource policy for the Vertical Pod Autoscaler. + resourcePolicy: + # -- Configures the container policies for the Vertical Pod Autoscaler. + containerPolicies: + - containerName: alloy + # -- The controlled resources for the Vertical Pod Autoscaler. + controlledResources: + - cpu + - memory + # -- The controlled values for the Vertical Pod Autoscaler. Needs to be either RequestsOnly or RequestsAndLimits. + controlledValues: "RequestsAndLimits" + # -- The maximum allowed values for the pods. + maxAllowed: {} + # cpu: 200m + # memory: 100Mi + # -- Defines the min allowed resources for the pod + minAllowed: {} + # cpu: 200m + # memory: 100Mi + + # -- Configures the update policy for the Vertical Pod Autoscaler. + updatePolicy: + # -- Specifies minimal number of replicas which need to be alive for VPA Updater to attempt pod eviction + # minReplicas: 1 + # -- Specifies whether recommended updates are applied when a Pod is started and whether recommended updates + # are applied during the life of a Pod. Possible values are "Off", "Initial", "Recreate", and "Auto". + # updateMode: Auto + + # -- Affinity configuration for pods. + affinity: {} + + volumes: + # -- Extra volumes to add to the Grafana Alloy pod. + extra: [] + + # -- volumeClaimTemplates to add when controller.type is 'statefulset'. + volumeClaimTemplates: [] + + ## -- Additional init containers to run. + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + ## + initContainers: [] + + # -- Additional containers to run alongside the Alloy container and initContainers. + extraContainers: [] + +service: + # -- Creates a Service for the controller's pods. + enabled: true + # -- Service type + type: ClusterIP + # -- NodePort port. Only takes effect when `service.type: NodePort` + nodePort: 31128 + # -- Cluster IP, can be set to None, empty "" or an IP address + clusterIP: '' + # -- Value for internal traffic policy. 'Cluster' or 'Local' + internalTrafficPolicy: Cluster + annotations: {} + # cloud.google.com/load-balancer-type: Internal + +serviceMonitor: + enabled: false + # -- Additional labels for the service monitor. + additionalLabels: {} + # -- Scrape interval. If not set, the Prometheus default scrape interval is used. + interval: "" + # -- MetricRelabelConfigs to apply to samples after scraping, but before ingestion. + # ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + # -- Customize tls parameters for the service monitor + tlsConfig: {} + + # -- RelabelConfigs to apply to samples before scraping + # ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace +ingress: + # -- Enables ingress for Alloy (Faro port) + enabled: false + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + # Values can be templated + annotations: + {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + labels: {} + path: / + faroPort: 12347 + + # pathType is only for k8s >= 1.1= + pathType: Prefix + + hosts: + - chart-example.local + ## Extra paths to prepend to every host configuration. This is useful when working with annotation based services. + extraPaths: [] + # - path: /* + # backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + ## Or for k8s > 1.19 + # - path: /* + # pathType: Prefix + # backend: + # service: + # name: ssl-redirect + # port: + # name: use-annotation + + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +# -- Extra k8s manifests to deploy +extraObjects: [] +# - apiVersion: v1 +# kind: Secret +# metadata: +# name: grafana-cloud +# stringData: +# PROMETHEUS_HOST: 'https://prometheus-us-central1.grafana.net/api/prom/push' +# PROMETHEUS_USERNAME: '123456' diff --git a/charts/mayastor/charts/crds/Chart.yaml b/charts/mayastor/charts/crds/Chart.yaml new file mode 100644 index 0000000..fc1d9db --- /dev/null +++ b/charts/mayastor/charts/crds/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +description: 'A Helm chart that collects CustomResourceDefinitions (CRDs) from Mayastor. ' +name: crds +version: 2.10.0 diff --git a/charts/mayastor/charts/crds/README.md b/charts/mayastor/charts/crds/README.md new file mode 100644 index 0000000..7b8aca3 --- /dev/null +++ b/charts/mayastor/charts/crds/README.md @@ -0,0 +1,12 @@ +# crds + +A Helm chart that collects CustomResourceDefinitions (CRDs) from Mayastor. + +## Values + +| Key | Description | Default | +|:----|:------------|:--------| +| csi.​volumeSnapshots.​annotations | Annotations to be added to all CRDs |
{

}
| +| csi.​volumeSnapshots.​enabled | Install Volume Snapshot CRDs | `true` | +| csi.​volumeSnapshots.​keep | Keep CRDs on chart uninstall | `true` | + diff --git a/charts/mayastor/charts/crds/templates/_helpers.tpl b/charts/mayastor/charts/crds/templates/_helpers.tpl new file mode 100644 index 0000000..d90113d --- /dev/null +++ b/charts/mayastor/charts/crds/templates/_helpers.tpl @@ -0,0 +1,20 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* + Adds extra annotations to CRDs. This targets two scenarios: preventing CRD recycling in case + the chart is removed; and adding custom annotations. + NOTE: This function assumes the element `metadata.annotations` already exists. + + Usage: + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} +*/}} + +{{- define "crds.extraAnnotations" -}} +{{- if .keep -}} +helm.sh/resource-policy: keep +{{ end }} +{{- with .annotations }} + {{- toYaml . }} +{{- end }} +{{- end -}} + diff --git a/charts/mayastor/charts/crds/templates/csi-volume-snapshot-class.yaml b/charts/mayastor/charts/crds/templates/csi-volume-snapshot-class.yaml new file mode 100644 index 0000000..ba00aa3 --- /dev/null +++ b/charts/mayastor/charts/crds/templates/csi-volume-snapshot-class.yaml @@ -0,0 +1,155 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: | + Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshotClass + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: false + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/mayastor/charts/crds/templates/csi-volume-snapshot-content.yaml b/charts/mayastor/charts/crds/templates/csi-volume-snapshot-content.yaml new file mode 100644 index 0000000..96c4a98 --- /dev/null +++ b/charts/mayastor/charts/crds/templates/csi-volume-snapshot-content.yaml @@ -0,0 +1,499 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + oneOf: + - required: + - snapshotHandle + - required: + - volumeHandle + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + sourceVolumeMode: + description: SourceVolumeMode is the mode of the volume whose snapshot + is taken. Can be either “Filesystem” or “Block”. If not specified, + it indicates the source volume's mode is unknown. This field is + immutable. This field is an alpha field. + type: string + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: | + If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future. + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: | + Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: | + creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + volumeGroupSnapshotContentName: + description: VolumeGroupSnapshotContentName is the name of the VolumeGroupSnapshotContent + of which this VolumeSnapshotContent is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshotContent + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: | + If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future. + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: | + Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/mayastor/charts/crds/templates/csi-volume-snapshot.yaml b/charts/mayastor/charts/crds/templates/csi-volume-snapshot.yaml new file mode 100644 index 0000000..024eb0d --- /dev/null +++ b/charts/mayastor/charts/crds/templates/csi-volume-snapshot.yaml @@ -0,0 +1,400 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + oneOf: + - required: + - persistentVolumeClaimName + - required: + - volumeSnapshotContentName + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + volumeSnapshotClassName: + description: | + VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field. + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: | + boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + x-kubernetes-int-or-string: true + volumeGroupSnapshotName: + description: VolumeGroupSnapshotName is the name of the VolumeGroupSnapshot + of which this VolumeSnapshot is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshot + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: | + spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required. + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + volumeSnapshotClassName: + description: | + VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field. + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: | + boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/mayastor/charts/crds/values.yaml b/charts/mayastor/charts/crds/values.yaml new file mode 100644 index 0000000..d3bb538 --- /dev/null +++ b/charts/mayastor/charts/crds/values.yaml @@ -0,0 +1,10 @@ +csi: + volumeSnapshots: + # -- Install Volume Snapshot CRDs + enabled: true + # -- Keep CRDs on chart uninstall + keep: true + # -- Annotations to be added to all CRDs + annotations: {} + # Example for Argo CD to prevent CRDs from being recycled + # argocd.argoproj.io/sync-options: Prune=false diff --git a/charts/mayastor/charts/etcd/.helmignore b/charts/mayastor/charts/etcd/.helmignore new file mode 100644 index 0000000..207983f --- /dev/null +++ b/charts/mayastor/charts/etcd/.helmignore @@ -0,0 +1,25 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +# img folder +img/ +# Changelog +CHANGELOG.md diff --git a/charts/mayastor/charts/etcd/Chart.lock b/charts/mayastor/charts/etcd/Chart.lock new file mode 100644 index 0000000..d665f89 --- /dev/null +++ b/charts/mayastor/charts/etcd/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + version: 2.31.1 +digest: sha256:38d6de6fd62a10417ff51df8b2c5e0cf294de80fe393c4e9f3247ca6433718fa +generated: "2025-05-23T12:49:29.352367+02:00" diff --git a/charts/mayastor/charts/etcd/Chart.yaml b/charts/mayastor/charts/etcd/Chart.yaml new file mode 100644 index 0000000..e989120 --- /dev/null +++ b/charts/mayastor/charts/etcd/Chart.yaml @@ -0,0 +1,35 @@ +annotations: + category: Database + images: | + - name: etcd + image: docker.io/bitnami/etcd:3.6.4-debian-12-r0 + - name: os-shell + image: docker.io/bitnami/os-shell:12-debian-12-r49 + licenses: Apache-2.0 + tanzuCategory: service +apiVersion: v2 +appVersion: 3.6.4 +dependencies: +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + tags: + - bitnami-common + version: 2.x.x +description: etcd is a distributed key-value store designed to securely store data + across a cluster. etcd is widely used in production on account of its reliability, + fault-tolerance and ease of use. +home: https://bitnami.com +icon: https://dyltqmyl993wv.cloudfront.net/assets/stacks/etcd/img/etcd-stack-220x234.png +keywords: +- etcd +- cluster +- database +- cache +- key-value +maintainers: +- name: Broadcom, Inc. All Rights Reserved. + url: https://github.com/bitnami/charts +name: etcd +sources: +- https://github.com/bitnami/charts/tree/main/bitnami/etcd +version: 12.0.14 diff --git a/charts/mayastor/charts/etcd/README.md b/charts/mayastor/charts/etcd/README.md new file mode 100644 index 0000000..feb2fcb --- /dev/null +++ b/charts/mayastor/charts/etcd/README.md @@ -0,0 +1,895 @@ + + +# Bitnami package for Etcd + +etcd is a distributed key-value store designed to securely store data across a cluster. etcd is widely used in production on account of its reliability, fault-tolerance and ease of use. + +[Overview of Etcd](https://etcd.io/) + +Trademarks: This software listing is packaged by Bitnami. The respective trademarks mentioned in the offering are owned by the respective companies, and use of them does not imply any affiliation or endorsement. + +## TL;DR + +```console +helm install my-release oci://registry-1.docker.io/bitnamicharts/etcd +``` + +Looking to use Etcd in production? Try [VMware Tanzu Application Catalog](https://bitnami.com/enterprise), the commercial edition of the Bitnami catalog. + +## ⚠️ Important Notice: Upcoming changes to the Bitnami Catalog + +Beginning August 28th, 2025, Bitnami will evolve its public catalog to offer a curated set of hardened, security-focused images under the new [Bitnami Secure Images initiative](https://news.broadcom.com/app-dev/broadcom-introduces-bitnami-secure-images-for-production-ready-containerized-applications). As part of this transition: + +- Granting community users access for the first time to security-optimized versions of popular container images. +- Bitnami will begin deprecating support for non-hardened, Debian-based software images in its free tier and will gradually remove non-latest tags from the public catalog. As a result, community users will have access to a reduced number of hardened images. These images are published only under the “latest” tag and are intended for development purposes +- Starting August 28th, over two weeks, all existing container images, including older or versioned tags (e.g., 2.50.0, 10.6), will be migrated from the public catalog (docker.io/bitnami) to the “Bitnami Legacy” repository (docker.io/bitnamilegacy), where they will no longer receive updates. +- For production workloads and long-term support, users are encouraged to adopt Bitnami Secure Images, which include hardened containers, smaller attack surfaces, CVE transparency (via VEX/KEV), SBOMs, and enterprise support. + +These changes aim to improve the security posture of all Bitnami users by promoting best practices for software supply chain integrity and up-to-date deployments. For more details, visit the [Bitnami Secure Images announcement](https://github.com/bitnami/containers/issues/83267). + +## Introduction + +This chart bootstraps a [etcd](https://github.com/bitnami/containers/tree/main/bitnami/etcd) deployment on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Kubernetes 1.23+ +- Helm 3.8.0+ +- PV provisioner support in the underlying infrastructure + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release oci://REGISTRY_NAME/REPOSITORY_NAME/etcd +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +These commands deploy etcd on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Configuration and installation details + +### Resource requests and limits + +Bitnami charts allow setting resource requests and limits for all containers inside the chart deployment. These are inside the `resources` value (check parameter table). Setting requests is essential for production workloads and these should be adapted to your specific use case. + +To make this process easier, the chart contains the `resourcesPreset` values, which automatically sets the `resources` section according to different presets. Check these presets in [the bitnami/common chart](https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15). However, in production workloads using `resourcesPreset` is discouraged as it may not fully adapt to your specific needs. Find more information on container resource management in the [official Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + +### [Rolling VS Immutable tags](https://techdocs.broadcom.com/us/en/vmware-tanzu/application-catalog/tanzu-application-catalog/services/tac-doc/apps-tutorials-understand-rolling-tags-containers-index.html) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### Prometheus metrics + +This chart can be integrated with Prometheus by setting `metrics.enabled` to true. This will expose the etcd native Prometheus port in the container and service (if `metrics.useSeparateEndpoint=true`). It will all have the necessary annotations to be automatically scraped by Prometheus. + +#### Prometheus requirements + +It is necessary to have a working installation of Prometheus or Prometheus Operator for the integration to work. Install the [Bitnami Prometheus helm chart](https://github.com/bitnami/charts/tree/main/bitnami/prometheus) or the [Bitnami Kube Prometheus helm chart](https://github.com/bitnami/charts/tree/main/bitnami/kube-prometheus) to easily have a working Prometheus in your cluster. + +#### Integration with Prometheus Operator + +The chart can deploy `PodMonitor` objects for integration with Prometheus Operator installations. To do so, set the value `*.metrics.podMonitor.enabled=true`. Ensure that the Prometheus Operator `CustomResourceDefinitions` are installed in the cluster or it will fail with the following error: + +```text +no matches for kind "PodMonitor" in version "monitoring.coreos.com/v1" +``` + +Install the [Bitnami Kube Prometheus helm chart](https://github.com/bitnami/charts/tree/main/bitnami/kube-prometheus) for having the necessary CRDs and the Prometheus Operator. + +### Update credentials + +Bitnami charts configure credentials at first boot. Any further change in the secrets or credentials require manual intervention. Follow these instructions: + +- Update the user password following [the upstream documentation](https://etcd.io/docs/latest/op-guide/authentication/) +- Update the password secret with the new values (replace the SECRET_NAME and PASSWORD placeholders) + +```shell +kubectl create secret generic SECRET_NAME --from-literal=etcd-root-password=PASSWORD --dry-run -o yaml | kubectl apply -f - +``` + +### Cluster configuration + +The Bitnami etcd chart can be used to bootstrap an etcd cluster, easy to scale and with available features to implement disaster recovery. It uses static discovery configured via environment variables to bootstrap the etcd cluster. Based on the number of initial replicas, and using the A records added to the DNS configuration by the headless service, the chart can calculate every advertised peer URL. + +The chart makes use of some extra elements offered by Kubernetes to ensure the bootstrapping is successful: + +- It sets a "Parallel" Pod Management Policy. This is critical, since all the etcd replicas should be created simultaneously to guarantee they can find each other. +- It records "not ready" pods in the DNS, so etcd replicas are reachable using their associated FQDN before they're actually ready. + +Learn more about [etcd discovery](https://etcd.io/docs/current/op-guide/clustering/#discovery), [Pod Management Policies](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies) and [recording "not ready" pods](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-hostname-and-subdomain-fields). + +Here is an example of the environment configuration bootstrapping an etcd cluster with 3 replicas: + +| Member | Variable | Value | +|---------|----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 0 | ETCD_NAME | etcd-0 | +| 0 | ETCD_INITIAL_ADVERTISE_PEER_URLS | | +|---------|----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 1 | ETCD_NAME | etcd-1 | +| 1 | ETCD_INITIAL_ADVERTISE_PEER_URLS | | +|---------|----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 2 | ETCD_NAME | etcd-2 | +| 2 | ETCD_INITIAL_ADVERTISE_PEER_URLS | | +|---------|----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| * | ETCD_INITIAL_CLUSTER_TOKEN | etcd-cluster-k8s | +| * | ETCD_INITIAL_CLUSTER | etcd-0=,etcd-1=,etcd-2= | + +The probes (readiness & liveness) are delayed 60 seconds by default, to give the etcd replicas time to start and find each other. After that period, the *etcdctl endpoint health* command is used to periodically perform health checks on every replica. + +#### Scalability + +The Bitnami etcd chart uses etcd reconfiguration operations to add/remove members of the cluster during scaling. + +When scaling down, a "pre-stop" lifecycle hook is used to ensure that the `etcdctl member remove` command is executed. The hook stores the output of this command in the persistent volume attached to the etcd pod. This hook is also executed when the pod is manually removed using the `kubectl delete pod` command or rescheduled by Kubernetes for any reason. This implies that the cluster can be scaled up/down without human intervention. + +Here is an example to explain how this works: + +1. An etcd cluster with three members running on a three-nodes Kubernetes cluster is bootstrapped. +2. After a few days, the cluster administrator decides to upgrade the kernel on one of the cluster nodes. To do so, the administrator drains the node. Pods running on that node are rescheduled to a different one. +3. During the pod eviction process, the "pre-stop" hook removes the etcd member from the cluster. Thus, the etcd cluster is scaled down to only two members. +4. Once the pod is scheduled on another node and initialized, the etcd member is added again to the cluster using the *etcdctl member add* command. Thus, the etcd cluster is scaled up to three replicas. + +If, for whatever reason, the "pre-stop" hook fails at removing the member, the initialization logic is able to detect that something went wrong by checking the `etcdctl member remove` command output that was stored in the persistent volume. It then uses the `etcdctl member update` command to add back the member. In this case, the cluster isn't automatically scaled down/up while the pod is recovered. Therefore, when other members attempt to connect to the pod, it may cause warnings or errors like the one below: + +```text +E | rafthttp: failed to dial XXXXXXXX on stream Message (peer XXXXXXXX failed to find local node YYYYYYYYY) +I | rafthttp: peer XXXXXXXX became inactive (message send to peer failed) +W | rafthttp: health check for peer XXXXXXXX could not connect: dial tcp A.B.C.D:2380: i/o timeout +``` + +Learn more about [etcd runtime configuration](https://etcd.io/docs/current/op-guide/runtime-configuration/) and how to safely [drain a Kubernetes node](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/). + +#### Cluster updates + +When updating the etcd StatefulSet (such as when upgrading the chart version via the *helm upgrade* command), every pod must be replaced following the StatefulSet update strategy. + +The chart uses a "RollingUpdate" strategy by default and with default Kubernetes values. In other words, it updates each Pod, one at a time, in the same order as Pod termination (from the largest ordinal to the smallest). It will wait until an updated Pod is "Running" and "Ready" prior to updating its predecessor. + +Learn more about [StatefulSet update strategies](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies). + +#### Disaster recovery + +If, for whatever reason, (N-1)/2 members of the cluster fail and the "pre-stop" hooks also fail at removing them from the cluster, the cluster disastrously fails, irrevocably losing quorum. Once quorum is lost, the cluster cannot reach consensus and therefore cannot continue accepting updates. Under this circumstance, the only possible solution is usually to restore the cluster from a snapshot. + +> IMPORTANT: All members should restore using the same snapshot. + +The Bitnami etcd chart solves this problem by optionally offering a Kubernetes cron job that periodically snapshots the keyspace and stores it in a RWX volume. In case the cluster disastrously fails, the pods will automatically try to restore it using the last avalable snapshot. + +[Learn how to enable this disaster recovery feature](#enable-disaster-recovery-features). + +The chart also sets by default a "soft" Pod AntiAffinity to reduce the risk of the cluster failing disastrously. + +Learn more about [etcd recovery](https://etcd.io/docs/current/op-guide/recovery), [Kubernetes cron jobs](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/) and [pod affinity and anti-affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) + +### Enable security for etcd + +The etcd chart can be configured with Role-based access control and TLS encryption to improve its security. + +#### Configure RBAC + +In order to enable Role-Based Access Control for etcd, set the following parameters: + +```text +auth.rbac.create=true +auth.rbac.rootPassword=ETCD_ROOT_PASSWORD +``` + +These parameters create a `root` user with an associate `root` role with access to everything. The remaining users will use the `guest` role and won't have permissions to do anything. + +#### Configure TLS for server-to-server communications + +In order to enable secure transport between peer nodes deploy the helm chart with these options: + +```text +auth.peer.secureTransport=true +auth.peer.useAutoTLS=true +``` + +#### Configure certificates for client communication + +In order to enable secure transport between client and server, create a secret containing the certificate and key files and the CA used to sign the client certificates. In this case, create the secret and then deploy the chart with these options: + +```text +auth.client.secureTransport=true +auth.client.enableAuthentication=true +auth.client.existingSecret=etcd-client-certs +``` + +Learn more about the [etcd security model](https://etcd.io/) and how to [generate self-signed certificates for etcd](https://coreos.com/os/docs/latest/generate-self-signed-certificates.html). + +### Enable disaster recovery features + +The Bitnami etcd Helm chart supports automatic disaster recovery by periodically snapshotting the keyspace. If the cluster permanently loses more than (N-1)/2 members, it tries to recover the cluster from a previous snapshot. + +Enable this feature with the following parameters: + +```text +persistence.enabled=true +disasterRecovery.enabled=true +disasterRecovery.pvc.size=2Gi +disasterRecovery.pvc.storageClassName=nfs +``` + +If the `startFromSnapshot.*` parameters are used at the same time as the `disasterRecovery.*` parameters, the PVC provided via the `startFromSnapshot.existingClaim` parameter will be used to store the periodical snapshots. + +> NOTE: The disaster recovery feature requires volumes with ReadWriteMany access mode. + +### Backup and restore + +Two different approaches are available to back up and restore this Helm Chart: + +- Back up the data from the source deployment and restore it in a new deployment using etcd's built-in backup/restore tools. +- Back up the persistent volumes from the source deployment and attach them to a new deployment using Velero, a Kubernetes backup/restore tool. + +#### Method 1: Backup and restore data using etcd's built-in tools + +This method involves the following steps: + +- Use the *etcdctl* tool to create a snapshot of the data in the source cluster. +- Make the snapshot available in a Kubernetes PersistentVolumeClaim (PVC) that supports ReadWriteMany access (for example, a PVC created with the NFS storage class) +- Restore the data snapshot in a new cluster using the <%= variable :catalog_name, :platform %> etcd Helm chart's *startFromSnapshot.existingClaim* and *startFromSnapshot.snapshotFilename* parameters to define the source PVC and source filename for the snapshot. + +> NOTE: Under this approach, it is important to create the new deployment on the destination cluster using the same credentials as the original deployment on the source cluster. + +#### Method 2: Back up and restore persistent data volumes + +This method involves copying the persistent data volumes for the etcd nodes and reusing them in a new deployment with [Velero](https://velero.io/), an open source Kubernetes backup/restore tool. This method is only suitable when: + +- The Kubernetes provider is [supported by Velero](https://velero.io/docs/latest/supported-providers/). +- Both clusters are on the same Kubernetes provider, as this is a requirement of [Velero's native support for migrating persistent volumes](https://velero.io/docs/latest/migration-case/). +- The restored deployment on the destination cluster will have the same name, namespace, topology and credentials as the original deployment on the source cluster. + +This method involves the following steps: + +- Install Velero on the source and destination clusters. +- Use Velero to back up the PersistentVolumes (PVs) used by the etcd deployment on the source cluster. +- Use Velero to restore the backed-up PVs on the destination cluster. +- Create a new etcd deployment on the destination cluster with the same deployment name, credentials and other parameters as the original. This new deployment will use the restored PVs and hence the original data. + +### Exposing etcd metrics + +The metrics exposed by etcd can be exposed to be scraped by Prometheus. Metrics can be scraped from within the cluster using any of the following approaches: + +- Adding the required annotations for Prometheus to discover the metrics endpoints, as in the example below: + +```yaml +podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/path: "/metrics/cluster" + prometheus.io/port: "9000" +``` + +- Creating a ServiceMonitor or PodMonitor entry (when the Prometheus Operator is available in the cluster) +- Using something similar to the [example Prometheus scrape configuration](https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml). + +If metrics are to be scraped from outside the cluster, the Kubernetes API proxy can be utilized to access the endpoint. + +### Using custom configuration + +In order to use custom configuration parameters, two options are available: + +- Using environment variables: etcd allows setting environment variables that map to configuration settings. In order to set extra environment variables, you can use the `extraEnvVars` property. Alternatively, you can use a ConfigMap or a Secret with the environment variables using the `extraEnvVarsCM` or the `extraEnvVarsSecret` properties. + +```yaml +extraEnvVars: + - name: ETCD_AUTO_COMPACTION_RETENTION + value: "0" + - name: ETCD_HEARTBEAT_INTERVAL + value: "150" +``` + +- Using a custom `etcd.conf.yml`: The etcd chart allows mounting a custom `etcd.conf.yml` file as ConfigMap. In order to so, you can use the `configuration` property. Alternatively, you can use an existing ConfigMap using the `existingConfigmap` parameter. + +### Auto Compaction + +Since etcd keeps an exact history of its keyspace, this history should be periodically compacted to avoid performance degradation and eventual storage space exhaustion. Compacting the keyspace history drops all information about keys superseded prior to a given keyspace revision. The space used by these keys then becomes available for additional writes to the keyspace. + +`autoCompactionMode`, by default periodic. Valid values: "periodic", "revision". + +- 'periodic' for duration based retention, defaulting to hours if no time unit is provided (e.g. "5m"). +- 'revision' for revision number based retention. +`autoCompactionRetention` for mvcc key value store in hour, by default 0, means disabled. + +You can enable auto compaction by using following parameters: + +```console +autoCompactionMode=periodic +autoCompactionRetention=10m +``` + +### Sidecars and Init Containers + +If you have a need for additional containers to run within the same pod as the etcd app (e.g. an additional metrics or logging exporter), you can do so via the `sidecars` config parameter. Simply define your container according to the Kubernetes container spec. + +```yaml +sidecars: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +Similarly, you can add extra init containers using the `initContainers` parameter. + +```yaml +initContainers: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +### Deploying extra resources + +There are cases where you may want to deploy extra objects, such a ConfigMap containing your app's configuration or some extra deployment with a micro service used by your app. For covering this case, the chart allows adding the full specification of other objects using the `extraDeploy` parameter. + +### Setting Pod's affinity + +This chart allows you to set your custom affinity using the `affinity` parameter. Find more information about Pod's affinity in the [kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). + +As an alternative, you can use of the preset configurations for pod affinity, pod anti-affinity, and node affinity available at the [bitnami/common](https://github.com/bitnami/charts/tree/main/bitnami/common#affinities) chart. To do so, set the `podAffinityPreset`, `podAntiAffinityPreset`, or `nodeAffinityPreset` parameters. + +## Persistence + +The [Bitnami etcd](https://github.com/bitnami/containers/tree/main/bitnami/etcd) image stores the etcd data at the `/bitnami/etcd` path of the container. Persistent Volume Claims are used to keep the data across statefulsets. + +The chart mounts a [Persistent Volume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) volume at this location. The volume is created using dynamic volume provisioning by default. An existing PersistentVolumeClaim can also be defined for this purpose. + +If you encounter errors when working with persistent volumes, refer to our [troubleshooting guide for persistent volumes](https://docs.bitnami.com/kubernetes/faq/troubleshooting/troubleshooting-persistence-volumes/). + +## Parameters + +### Global parameters + +| Name | Description | Value | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `global.imageRegistry` | Global Docker image registry | `""` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | +| `global.defaultStorageClass` | Global default StorageClass for Persistent Volume(s) | `""` | +| `global.security.allowInsecureImages` | Allows skipping image verification | `false` | +| `global.compatibility.openshift.adaptSecurityContext` | Adapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation) | `auto` | + +### Common parameters + +| Name | Description | Value | +| ------------------------ | -------------------------------------------------------------------------------------------- | --------------- | +| `kubeVersion` | Force target Kubernetes version (using Helm capabilities if not set) | `""` | +| `nameOverride` | String to partially override common.names.fullname template (will maintain the release name) | `""` | +| `fullnameOverride` | String to fully override common.names.fullname template | `""` | +| `namespaceOverride` | String to fully override common.names.namespace template | `""` | +| `commonLabels` | Labels to add to all deployed objects | `{}` | +| `commonAnnotations` | Annotations to add to all deployed objects | `{}` | +| `clusterDomain` | Default Kubernetes cluster domain | `cluster.local` | +| `extraDeploy` | Array of extra objects to deploy with the release | `[]` | +| `usePasswordFiles` | Mount credentials as files instead of using environment variables | `true` | +| `diagnosticMode.enabled` | Enable diagnostic mode (all probes will be disabled and the command will be overridden) | `false` | +| `diagnosticMode.command` | Command to override all containers in the deployment | `["sleep"]` | +| `diagnosticMode.args` | Args to override all containers in the deployment | `["infinity"]` | + +### etcd parameters + +| Name | Description | Value | +| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `image.registry` | etcd image registry | `REGISTRY_NAME` | +| `image.repository` | etcd image name | `REPOSITORY_NAME/etcd` | +| `image.digest` | etcd image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `image.pullPolicy` | etcd image pull policy | `IfNotPresent` | +| `image.pullSecrets` | etcd image pull secrets | `[]` | +| `image.debug` | Enable image debug mode | `false` | +| `auth.rbac.create` | Switch to enable RBAC authentication | `true` | +| `auth.rbac.allowNoneAuthentication` | Allow to use etcd without configuring RBAC authentication | `true` | +| `auth.rbac.rootPassword` | Root user password. The root user is always `root` | `""` | +| `auth.rbac.existingSecret` | Name of the existing secret containing credentials for the root user | `""` | +| `auth.rbac.existingSecretPasswordKey` | Name of key containing password to be retrieved from the existing secret | `""` | +| `auth.token.enabled` | Enables token authentication | `true` | +| `auth.token.type` | Authentication token type. Allowed values: 'simple' or 'jwt' | `jwt` | +| `auth.token.privateKey.filename` | Name of the file containing the private key for signing the JWT token | `jwt-token.pem` | +| `auth.token.privateKey.existingSecret` | Name of the existing secret containing the private key for signing the JWT token | `""` | +| `auth.token.signMethod` | JWT token sign method | `RS256` | +| `auth.token.ttl` | JWT token TTL | `10m` | +| `auth.client.secureTransport` | Switch to encrypt client-to-server communications using TLS certificates | `false` | +| `auth.client.useAutoTLS` | Switch to automatically create the TLS certificates | `false` | +| `auth.client.existingSecret` | Name of the existing secret containing the TLS certificates for client-to-server communications | `""` | +| `auth.client.enableAuthentication` | Switch to enable host authentication using TLS certificates. Requires existing secret | `false` | +| `auth.client.certFilename` | Name of the file containing the client certificate | `cert.pem` | +| `auth.client.certKeyFilename` | Name of the file containing the client certificate private key | `key.pem` | +| `auth.client.caFilename` | Name of the file containing the client CA certificate | `""` | +| `auth.peer.secureTransport` | Switch to encrypt server-to-server communications using TLS certificates | `false` | +| `auth.peer.useAutoTLS` | Switch to automatically create the TLS certificates | `false` | +| `auth.peer.existingSecret` | Name of the existing secret containing the TLS certificates for server-to-server communications | `""` | +| `auth.peer.enableAuthentication` | Switch to enable host authentication using TLS certificates. Requires existing secret | `false` | +| `auth.peer.certFilename` | Name of the file containing the peer certificate | `cert.pem` | +| `auth.peer.certKeyFilename` | Name of the file containing the peer certificate private key | `key.pem` | +| `auth.peer.caFilename` | Name of the file containing the peer CA certificate | `""` | +| `autoCompactionMode` | Auto compaction mode, by default periodic. Valid values: "periodic", "revision". | `""` | +| `autoCompactionRetention` | Auto compaction retention for mvcc key value store in hour, by default 0, means disabled | `""` | +| `initialClusterToken` | Initial cluster token. Can be used to protect etcd from cross-cluster-interaction, which might corrupt the clusters. | `etcd-cluster-k8s` | +| `logLevel` | Sets the log level for the etcd process. Allowed values: 'debug', 'info', 'warn', 'error', 'panic', 'fatal' | `info` | +| `maxProcs` | Limits the number of operating system threads that can execute user-level | `""` | +| `configuration` | etcd configuration. Specify content for etcd.conf.yml | `""` | +| `existingConfigmap` | Existing ConfigMap with etcd configuration | `""` | +| `extraEnvVars` | Extra environment variables to be set on etcd container | `[]` | +| `extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars | `""` | +| `extraEnvVarsSecret` | Name of existing Secret containing extra env vars | `""` | +| `command` | Default container command (useful when using custom images) | `[]` | +| `args` | Default container args (useful when using custom images) | `[]` | + +### etcd statefulset parameters + +| Name | Description | Value | +| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `replicaCount` | Number of etcd replicas to deploy | `1` | +| `updateStrategy.type` | Update strategy type, can be set to RollingUpdate or OnDelete. | `RollingUpdate` | +| `podManagementPolicy` | Pod management policy for the etcd statefulset | `Parallel` | +| `automountServiceAccountToken` | Mount Service Account token in pod | `false` | +| `hostAliases` | etcd pod host aliases | `[]` | +| `lifecycleHooks` | Override default etcd container hooks | `{}` | +| `containerPorts.client` | Client port to expose at container level | `2379` | +| `containerPorts.peer` | Peer port to expose at container level | `2380` | +| `containerPorts.metrics` | Metrics port to expose at container level when metrics.useSeparateEndpoint is true | `9090` | +| `podSecurityContext.enabled` | Enabled etcd pods' Security Context | `true` | +| `podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy | `Always` | +| `podSecurityContext.sysctls` | Set kernel settings using the sysctl interface | `[]` | +| `podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | +| `podSecurityContext.fsGroup` | Set etcd pod's Security Context fsGroup | `1001` | +| `containerSecurityContext.enabled` | Enabled etcd containers' Security Context | `true` | +| `containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | +| `containerSecurityContext.runAsUser` | Set etcd containers' Security Context runAsUser | `1001` | +| `containerSecurityContext.runAsGroup` | Set etcd containers' Security Context runAsUser | `1001` | +| `containerSecurityContext.runAsNonRoot` | Set Controller container's Security Context runAsNonRoot | `true` | +| `containerSecurityContext.privileged` | Set primary container's Security Context privileged | `false` | +| `containerSecurityContext.allowPrivilegeEscalation` | Set primary container's Security Context allowPrivilegeEscalation | `false` | +| `containerSecurityContext.readOnlyRootFilesystem` | Set container's Security Context readOnlyRootFilesystem | `true` | +| `containerSecurityContext.capabilities.drop` | List of capabilities to be dropped | `["ALL"]` | +| `containerSecurityContext.seccompProfile.type` | Set container's Security Context seccomp profile | `RuntimeDefault` | +| `resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `micro` | +| `resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `livenessProbe.enabled` | Enable livenessProbe | `true` | +| `livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `60` | +| `livenessProbe.periodSeconds` | Period seconds for livenessProbe | `30` | +| `livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `5` | +| `livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `5` | +| `livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `readinessProbe.enabled` | Enable readinessProbe | `true` | +| `readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `60` | +| `readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `5` | +| `readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `5` | +| `readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `startupProbe.enabled` | Enable startupProbe | `false` | +| `startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `0` | +| `startupProbe.periodSeconds` | Period seconds for startupProbe | `10` | +| `startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `5` | +| `startupProbe.failureThreshold` | Failure threshold for startupProbe | `60` | +| `startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `customLivenessProbe` | Override default liveness probe | `{}` | +| `customReadinessProbe` | Override default readiness probe | `{}` | +| `customStartupProbe` | Override default startup probe | `{}` | +| `extraVolumes` | Optionally specify extra list of additional volumes for etcd pods | `[]` | +| `extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for etcd container(s) | `[]` | +| `extraVolumeClaimTemplates` | Optionally specify extra list of additional volumeClaimTemplates for etcd container(s) | `[]` | +| `initContainers` | Add additional init containers to the etcd pods | `[]` | +| `sidecars` | Add additional sidecar containers to the etcd pods | `[]` | +| `podAnnotations` | Annotations for etcd pods | `{}` | +| `podLabels` | Extra labels for etcd pods | `{}` | +| `podAffinityPreset` | Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `nodeAffinityPreset.type` | Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `nodeAffinityPreset.key` | Node label key to match. Ignored if `affinity` is set. | `""` | +| `nodeAffinityPreset.values` | Node label values to match. Ignored if `affinity` is set. | `[]` | +| `affinity` | Affinity for pod assignment | `{}` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `tolerations` | Tolerations for pod assignment | `[]` | +| `terminationGracePeriodSeconds` | Seconds the pod needs to gracefully terminate | `""` | +| `schedulerName` | Name of the k8s scheduler (other than default) | `""` | +| `priorityClassName` | Name of the priority class to be used by etcd pods | `""` | +| `runtimeClassName` | Name of the runtime class to be used by pod(s) | `""` | +| `shareProcessNamespace` | Enable shared process namespace in a pod. | `false` | +| `topologySpreadConstraints` | Topology Spread Constraints for pod assignment | `[]` | +| `persistentVolumeClaimRetentionPolicy.enabled` | Controls if and how PVCs are deleted during the lifecycle of a StatefulSet | `false` | +| `persistentVolumeClaimRetentionPolicy.whenScaled` | Volume retention behavior when the replica count of the StatefulSet is reduced | `Retain` | +| `persistentVolumeClaimRetentionPolicy.whenDeleted` | Volume retention behavior that applies when the StatefulSet is deleted | `Retain` | + +### Traffic exposure parameters + +| Name | Description | Value | +| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| `service.type` | Kubernetes Service type | `ClusterIP` | +| `service.enabled` | create second service if equal true | `true` | +| `service.clusterIP` | Kubernetes service Cluster IP | `""` | +| `service.ports.client` | etcd client port | `2379` | +| `service.ports.peer` | etcd peer port | `2380` | +| `service.ports.metrics` | etcd metrics port when metrics.useSeparateEndpoint is true | `9090` | +| `service.nodePorts.client` | Specify the nodePort client value for the LoadBalancer and NodePort service types. | `""` | +| `service.nodePorts.peer` | Specify the nodePort peer value for the LoadBalancer and NodePort service types. | `""` | +| `service.nodePorts.metrics` | Specify the nodePort metrics value for the LoadBalancer and NodePort service types. The metrics port is only exposed when metrics.useSeparateEndpoint is true. | `""` | +| `service.clientPortNameOverride` | etcd client port name override | `""` | +| `service.peerPortNameOverride` | etcd peer port name override | `""` | +| `service.metricsPortNameOverride` | etcd metrics port name override. The metrics port is only exposed when metrics.useSeparateEndpoint is true. | `""` | +| `service.loadBalancerIP` | loadBalancerIP for the etcd service (optional, cloud specific) | `""` | +| `service.loadBalancerClass` | loadBalancerClass for the etcd service (optional, cloud specific) | `""` | +| `service.loadBalancerSourceRanges` | Load Balancer source ranges | `[]` | +| `service.externalIPs` | External IPs | `[]` | +| `service.externalTrafficPolicy` | %%MAIN_CONTAINER_NAME%% service external traffic policy | `Cluster` | +| `service.extraPorts` | Extra ports to expose (normally used with the `sidecar` value) | `[]` | +| `service.annotations` | Additional annotations for the etcd service | `{}` | +| `service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `service.headless.annotations` | Annotations for the headless service. | `{}` | + +### Persistence parameters + +| Name | Description | Value | +| -------------------------- | --------------------------------------------------------------- | ------------------- | +| `persistence.enabled` | If true, use a Persistent Volume Claim. If false, use emptyDir. | `true` | +| `persistence.storageClass` | Persistent Volume Storage Class | `""` | +| `persistence.annotations` | Annotations for the PVC | `{}` | +| `persistence.labels` | Labels for the PVC | `{}` | +| `persistence.accessModes` | Persistent Volume Access Modes | `["ReadWriteOnce"]` | +| `persistence.size` | PVC Storage Request for etcd data volume | `8Gi` | +| `persistence.selector` | Selector to match an existing Persistent Volume | `{}` | + +### Volume Permissions parameters + +| Name | Description | Value | +| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `volumePermissions.enabled` | Enable init container that changes the owner and group of the persistent volume(s) mountpoint to `runAsUser:fsGroup` | `false` | +| `volumePermissions.image.registry` | Init container volume-permissions image registry | `REGISTRY_NAME` | +| `volumePermissions.image.repository` | Init container volume-permissions image name | `REPOSITORY_NAME/os-shell` | +| `volumePermissions.image.digest` | Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `IfNotPresent` | +| `volumePermissions.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `volumePermissions.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production). | `nano` | +| `volumePermissions.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | + +### Network Policy parameters + +| Name | Description | Value | +| --------------------------------------- | --------------------------------------------------------------- | ------ | +| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources | `true` | +| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | +| `networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` | +| `networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `networkPolicy.ingressNSMatchLabels` | Labels to match to allow traffic from other namespaces | `{}` | +| `networkPolicy.ingressNSPodMatchLabels` | Pod labels to match to allow traffic from other namespaces | `{}` | + +### Metrics parameters + +| Name | Description | Value | +| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `metrics.enabled` | Expose etcd metrics | `false` | +| `metrics.useSeparateEndpoint` | Use a separate endpoint for exposing metrics | `false` | +| `metrics.podAnnotations` | Annotations for the Prometheus metrics on etcd pods | `{}` | +| `metrics.podMonitor.enabled` | Create PodMonitor Resource for scraping metrics using PrometheusOperator | `false` | +| `metrics.podMonitor.namespace` | Namespace in which Prometheus is running | `monitoring` | +| `metrics.podMonitor.interval` | Specify the interval at which metrics should be scraped | `30s` | +| `metrics.podMonitor.scrapeTimeout` | Specify the timeout after which the scrape is ended | `30s` | +| `metrics.podMonitor.additionalLabels` | Additional labels that can be used so PodMonitors will be discovered by Prometheus | `{}` | +| `metrics.podMonitor.scheme` | Scheme to use for scraping | `http` | +| `metrics.podMonitor.tlsConfig` | TLS configuration used for scrape endpoints used by Prometheus | `{}` | +| `metrics.podMonitor.relabelings` | Prometheus relabeling rules | `[]` | +| `metrics.prometheusRule.enabled` | Create a Prometheus Operator PrometheusRule (also requires `metrics.enabled` to be `true` and `metrics.prometheusRule.rules`) | `false` | +| `metrics.prometheusRule.namespace` | Namespace for the PrometheusRule Resource (defaults to the Release Namespace) | `""` | +| `metrics.prometheusRule.additionalLabels` | Additional labels that can be used so PrometheusRule will be discovered by Prometheus | `{}` | +| `metrics.prometheusRule.rules` | Prometheus Rule definitions | `[]` | + +### Snapshotting parameters + +| Name | Description | Value | +| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `startFromSnapshot.enabled` | Initialize new cluster recovering an existing snapshot | `false` | +| `startFromSnapshot.existingClaim` | Existing PVC containing the etcd snapshot | `""` | +| `startFromSnapshot.snapshotFilename` | Snapshot filename | `""` | +| `disasterRecovery.enabled` | Enable auto disaster recovery by periodically snapshotting the keyspace | `false` | +| `disasterRecovery.cronjob.schedule` | Schedule in Cron format to save snapshots | `*/30 * * * *` | +| `disasterRecovery.cronjob.historyLimit` | Number of successful finished jobs to retain | `1` | +| `disasterRecovery.cronjob.snapshotHistoryLimit` | Number of etcd snapshots to retain, tagged by date | `1` | +| `disasterRecovery.cronjob.snapshotsDir` | Directory to store snapshots | `/snapshots` | +| `disasterRecovery.cronjob.podAnnotations` | Pod annotations for cronjob pods | `{}` | +| `disasterRecovery.cronjob.podSecurityContext.enabled` | Enable security context for Snapshotter pods | `true` | +| `disasterRecovery.cronjob.podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy | `Always` | +| `disasterRecovery.cronjob.podSecurityContext.sysctls` | Set kernel settings using the sysctl interface | `[]` | +| `disasterRecovery.cronjob.podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | +| `disasterRecovery.cronjob.podSecurityContext.fsGroup` | Group ID for the Snapshotter filesystem | `1001` | +| `disasterRecovery.cronjob.containerSecurityContext.enabled` | Enabled containers' Security Context | `true` | +| `disasterRecovery.cronjob.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | +| `disasterRecovery.cronjob.containerSecurityContext.runAsUser` | Set containers' Security Context runAsUser | `1001` | +| `disasterRecovery.cronjob.containerSecurityContext.runAsGroup` | Set containers' Security Context runAsGroup | `1001` | +| `disasterRecovery.cronjob.containerSecurityContext.runAsNonRoot` | Set container's Security Context runAsNonRoot | `true` | +| `disasterRecovery.cronjob.containerSecurityContext.privileged` | Set container's Security Context privileged | `false` | +| `disasterRecovery.cronjob.containerSecurityContext.readOnlyRootFilesystem` | Set container's Security Context readOnlyRootFilesystem | `true` | +| `disasterRecovery.cronjob.containerSecurityContext.allowPrivilegeEscalation` | Set container's Security Context allowPrivilegeEscalation | `false` | +| `disasterRecovery.cronjob.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped | `["ALL"]` | +| `disasterRecovery.cronjob.containerSecurityContext.seccompProfile.type` | Set container's Security Context seccomp profile | `RuntimeDefault` | +| `disasterRecovery.cronjob.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if disasterRecovery.cronjob.resources is set (disasterRecovery.cronjob.resources is recommended for production). | `nano` | +| `disasterRecovery.cronjob.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `disasterRecovery.cronjob.nodeSelector` | Node labels for cronjob pods assignment | `{}` | +| `disasterRecovery.cronjob.tolerations` | Tolerations for cronjob pods assignment | `[]` | +| `disasterRecovery.cronjob.podLabels` | Labels that will be added to pods created by cronjob | `{}` | +| `disasterRecovery.cronjob.serviceAccountName` | Specifies the service account to use for disaster recovery cronjob | `""` | +| `disasterRecovery.cronjob.command` | Override default snapshot container command (useful when you want to customize the snapshot logic) | `[]` | +| `disasterRecovery.pvc.existingClaim` | A manually managed Persistent Volume and Claim | `""` | +| `disasterRecovery.pvc.size` | PVC Storage Request | `2Gi` | +| `disasterRecovery.pvc.storageClassName` | Storage Class for snapshots volume | `nfs` | +| `disasterRecovery.pvc.subPath` | Path within the volume from which to mount | `""` | + +### Service account parameters + +| Name | Description | Value | +| --------------------------------------------- | ------------------------------------------------------------ | ------- | +| `serviceAccount.create` | Enable/disable service account creation | `true` | +| `serviceAccount.name` | Name of the service account to create or use | `""` | +| `serviceAccount.automountServiceAccountToken` | Enable/disable auto mounting of service account token | `false` | +| `serviceAccount.annotations` | Additional annotations to be included on the service account | `{}` | +| `serviceAccount.labels` | Additional labels to be included on the service account | `{}` | + +### etcd "pre-upgrade" K8s Job parameters + +| Name | Description | Value | +| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `preUpgradeJob.enabled` | Enable running a pre-upgrade job on Helm upgrades that removes obsolete members | `true` | +| `preUpgradeJob.annotations` | Add annotations to the etcd "pre-upgrade" job | `{}` | +| `preUpgradeJob.podLabels` | Additional pod labels for etcd "pre-upgrade" job | `{}` | +| `preUpgradeJob.podAnnotations` | Additional pod annotations for etcd "pre-upgrade" job | `{}` | +| `preUpgradeJob.podAffinityPreset` | Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `preUpgradeJob.podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `preUpgradeJob.nodeAffinityPreset.type` | Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `preUpgradeJob.nodeAffinityPreset.key` | Node label key to match. Ignored if `affinity` is set. | `""` | +| `preUpgradeJob.nodeAffinityPreset.values` | Node label values to match. Ignored if `affinity` is set. | `[]` | +| `preUpgradeJob.affinity` | Affinity for pod assignment | `{}` | +| `preUpgradeJob.nodeSelector` | Node labels for pod assignment | `{}` | +| `preUpgradeJob.tolerations` | Tolerations for pod assignment | `[]` | +| `preUpgradeJob.containerSecurityContext.enabled` | Enabled "pre-upgrade" job's containers' Security Context | `true` | +| `preUpgradeJob.containerSecurityContext.seLinuxOptions` | Set SELinux options in "pre-upgrade" job's containers | `{}` | +| `preUpgradeJob.containerSecurityContext.runAsUser` | Set runAsUser in "pre-upgrade" job's containers' Security Context | `1001` | +| `preUpgradeJob.containerSecurityContext.runAsGroup` | Set runAsUser in "pre-upgrade" job's containers' Security Context | `1001` | +| `preUpgradeJob.containerSecurityContext.runAsNonRoot` | Set runAsNonRoot in "pre-upgrade" job's containers' Security Context | `true` | +| `preUpgradeJob.containerSecurityContext.readOnlyRootFilesystem` | Set readOnlyRootFilesystem in "pre-upgrade" job's containers' Security Context | `true` | +| `preUpgradeJob.containerSecurityContext.privileged` | Set privileged in "pre-upgrade" job's containers' Security Context | `false` | +| `preUpgradeJob.containerSecurityContext.allowPrivilegeEscalation` | Set allowPrivilegeEscalation in "pre-upgrade" job's containers' Security Context | `false` | +| `preUpgradeJob.containerSecurityContext.capabilities.add` | List of capabilities to be added in "pre-upgrade" job's containers | `[]` | +| `preUpgradeJob.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped in "pre-upgrade" job's containers | `["ALL"]` | +| `preUpgradeJob.containerSecurityContext.seccompProfile.type` | Set seccomp profile in "pre-upgrade" job's containers | `RuntimeDefault` | +| `preUpgradeJob.podSecurityContext.enabled` | Enabled "pre-upgrade" job's pods' Security Context | `true` | +| `preUpgradeJob.podSecurityContext.fsGroupChangePolicy` | Set fsGroupChangePolicy in "pre-upgrade" job's pods' Security Context | `Always` | +| `preUpgradeJob.podSecurityContext.sysctls` | List of sysctls to allow in "pre-upgrade" job's pods' Security Context | `[]` | +| `preUpgradeJob.podSecurityContext.supplementalGroups` | List of supplemental groups to add to "pre-upgrade" job's pods' Security Context | `[]` | +| `preUpgradeJob.podSecurityContext.fsGroup` | Set fsGroup in "pre-upgrade" job's pods' Security Context | `1001` | +| `preUpgradeJob.resourcesPreset` | Set etcd "pre-upgrade" job's container resources according to one common preset (allowed values: none, nano, small, medium, large, xlarge, 2xlarge). This is ignored if preUpgradeJob.resources is set (preUpgradeJob.resources is recommended for production). | `micro` | +| `preUpgradeJob.resources` | Set etcd "pre-upgrade" job's container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `preUpgradeJob.startDelay` | Optional delay before starting the pre-upgrade hook (in seconds). | `""` | + +### Defragmentation parameters + +| Name | Description | Value | +| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | +| `defrag.enabled` | Enable automatic defragmentation. This is most effective when paired with auto compaction: consider setting "autoCompactionRetention > 0". | `false` | +| `defrag.cronjob.startingDeadlineSeconds` | Number of seconds representing the deadline for starting the job if it misses scheduled time for any reason | `""` | +| `defrag.cronjob.schedule` | Schedule in Cron format to defrag (daily at midnight by default) | `0 0 * * *` | +| `defrag.cronjob.concurrencyPolicy` | Set the cronjob parameter concurrencyPolicy | `Forbid` | +| `defrag.cronjob.suspend` | Boolean that indicates if the controller must suspend subsequent executions (not applied to already started executions) | `false` | +| `defrag.cronjob.successfulJobsHistoryLimit` | Number of successful finished jobs to retain | `1` | +| `defrag.cronjob.failedJobsHistoryLimit` | Number of failed finished jobs to retain | `1` | +| `defrag.cronjob.labels` | Additional labels to be added to the Defrag cronjob | `{}` | +| `defrag.cronjob.annotations` | Annotations to be added to the Defrag cronjob | `{}` | +| `defrag.cronjob.activeDeadlineSeconds` | Number of seconds relative to the startTime that the job may be continuously active before the system tries to terminate it | `""` | +| `defrag.cronjob.restartPolicy` | Set the cronjob parameter restartPolicy | `OnFailure` | +| `defrag.cronjob.podLabels` | Labels that will be added to pods created by Defrag cronjob | `{}` | +| `defrag.cronjob.podAnnotations` | Pod annotations for Defrag cronjob pods | `{}` | +| `defrag.cronjob.podSecurityContext.enabled` | Enable security context for Defrag pods | `true` | +| `defrag.cronjob.podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy | `Always` | +| `defrag.cronjob.podSecurityContext.sysctls` | Set kernel settings using the sysctl interface | `[]` | +| `defrag.cronjob.podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | +| `defrag.cronjob.podSecurityContext.fsGroup` | Group ID for the Defrag filesystem | `1001` | +| `defrag.cronjob.containerSecurityContext.enabled` | Enabled containers' Security Context | `true` | +| `defrag.cronjob.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | +| `defrag.cronjob.containerSecurityContext.runAsUser` | Set containers' Security Context runAsUser | `1001` | +| `defrag.cronjob.containerSecurityContext.runAsGroup` | Set containers' Security Context runAsGroup | `1001` | +| `defrag.cronjob.containerSecurityContext.runAsNonRoot` | Set container's Security Context runAsNonRoot | `true` | +| `defrag.cronjob.containerSecurityContext.privileged` | Set container's Security Context privileged | `false` | +| `defrag.cronjob.containerSecurityContext.readOnlyRootFilesystem` | Set container's Security Context readOnlyRootFilesystem | `true` | +| `defrag.cronjob.containerSecurityContext.allowPrivilegeEscalation` | Set container's Security Context allowPrivilegeEscalation | `false` | +| `defrag.cronjob.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped | `["ALL"]` | +| `defrag.cronjob.containerSecurityContext.seccompProfile.type` | Set container's Security Context seccomp profile | `RuntimeDefault` | +| `defrag.cronjob.nodeSelector` | Node labels for pod assignment in Defrag cronjob | `{}` | +| `defrag.cronjob.tolerations` | Tolerations for pod assignment in Defrag cronjob | `[]` | +| `defrag.cronjob.serviceAccountName` | Specifies the service account to use for Defrag cronjob | `""` | +| `defrag.cronjob.command` | Override default container command for defragmentation (useful when using custom images) | `[]` | +| `defrag.cronjob.args` | Override default container args (useful when using custom images) | `[]` | +| `defrag.cronjob.resourcesPreset` | Set container resources according to one common preset | `nano` | +| `defrag.cronjob.resources` | Set container requests and limits for different resources like CPU or | `{}` | +| `defrag.cronjob.extraEnvVars` | Extra environment variables to be set on defrag cronjob container | `[]` | +| `defrag.cronjob.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars | `""` | +| `defrag.cronjob.extraEnvVarsSecret` | Name of existing Secret containing extra env vars | `""` | + +### Other parameters + +| Name | Description | Value | +| -------------------- | -------------------------------------------------------------- | ------ | +| `pdb.create` | Enable/disable a Pod Disruption Budget creation | `true` | +| `pdb.minAvailable` | Minimum number/percentage of pods that should remain scheduled | `51%` | +| `pdb.maxUnavailable` | Maximum number/percentage of pods that may be made unavailable | `""` | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +helm install my-release \ + --set auth.rbac.rootPassword=secretpassword oci://REGISTRY_NAME/REPOSITORY_NAME/etcd +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +The above command sets the etcd `root` account password to `secretpassword`. + +> NOTE: Once this chart is deployed, it is not possible to change the application's access credentials, such as usernames or passwords, using Helm. To change these application credentials after deployment, delete any persistent volumes (PVs) used by the chart and re-deploy it, or use the application's built-in administrative tools if available. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```console +helm install my-release -f values.yaml oci://REGISTRY_NAME/REPOSITORY_NAME/etcd +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. +> **Tip**: You can use the default [values.yaml](https://github.com/bitnami/charts/tree/main/bitnami/etcd/values.yaml) + +## Troubleshooting + +Find more information about how to deal with common errors related to Bitnami's Helm charts in [this troubleshooting guide](https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues). + +## Upgrading + +### To 11.0.0 + +This version introduces the following breaking changes: + +- Remove `initialClusterState` which was unreliable at detecting cluster state. From now on, each node will contact other members to determine cluster state. If no members are available and the data dir is empty, then it bootstraps a new cluster. +- Remove `removeMemberOnContainerTermination` which was unreliable at removing stale members during replica count updates. Instead, a pre-upgrade hook is added to check and remove stale members. +- Remove support for manual scaling with `kubectl` or autoscaler. Upgrading of any kind including increasing replica count must be done with `helm upgrade` exclusively. CD automation tools that respect Helm hooks such as ArgoCD can also be used. + +### To 10.7.0 + +This version introduces image verification for security purposes. To disable it, set `global.security.allowInsecureImages` to `true`. More details at [GitHub issue](https://github.com/bitnami/charts/issues/30850). + +### To 10.0.0 + +This major bump changes the following security defaults: + +- `runAsGroup` is changed from `0` to `1001` +- `readOnlyRootFilesystem` is set to `true` +- `resourcesPreset` is changed from `none` to the minimum size working in our test suites (NOTE: `resourcesPreset` is not meant for production usage, but `resources` adapted to your use case). +- `global.compatibility.openshift.adaptSecurityContext` is changed from `disabled` to `auto`. + +This could potentially break any customization or init scripts used in your deployment. If this is the case, change the default values to the previous ones. + +### To 9.0.0 + +This version adds a new label `app.kubernetes.io/component=etcd` to the StatefulSet and pods. Due to this change, the StatefulSet will be replaced (as it's not possible to add additional `spec.selector.matchLabels` to an existing StatefulSet) and the pods will be recreated. To upgrade to this version from a previous version, you need to run the following steps: + +1. Add new label to your pods + + ```console + kubectl label pod my-release-0 app.kubernetes.io/component=etcd + # Repeat for all etcd pods, based on configured .replicaCount (excluding the etcd snappshoter pod, if .disasterRecovery.enabled is set to true) + ```` + +2. Remove the StatefulSet keeping the pods: + + ```console + kubectl delete statefulset my-release --cascade=orphan + ``` + +3. Upgrade your cluster: + + ```console + helm upgrade my-release oci://REGISTRY_NAME/REPOSITORY_NAME/etcd --set auth.rbac.rootPassword=$ETCD_ROOT_PASSWORD + ``` + + > Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +### To 8.0.0 + +This version reverts the change in the previous major bump ([7.0.0](https://github.com/bitnami/charts/tree/main/bitnami/etcd#to-700)). Now the default `etcd` branch is `3.5` again once confirmed by the [etcd developers](https://github.com/etcd-io/etcd/tree/main/CHANGELOG#production-recommendation) that this version is production-ready once solved the data corruption issue. + +### To 7.0.0 + +This version changes the default `etcd` branch to `3.4` as suggested by [etcd developers](https://github.com/etcd-io/etcd/tree/main/CHANGELOG#production-recommendation). In order to migrate the data follow the official etcd instructions. + +### To 6.0.0 + +This version introduces several features and performance improvements: + +- The statefulset can now be scaled using `kubectl scale` command. Using `helm upgrade` to recalculate available endpoints is no longer needed. +- The scripts used for bootstrapping, runtime reconfiguration, and disaster recovery have been refactored and moved to the etcd container with two purposes: removing technical debt & improving the stability. +- Several parameters were reorganized to simplify the structure and follow the same standard used on other Bitnami charts: + - `etcd.initialClusterState` is renamed to `initialClusterState`. + - `statefulset.replicaCount` is renamed to `replicaCount`. + - `statefulset.podManagementPolicy` is renamed to `podManagementPolicy`. + - `statefulset.updateStrategy` and `statefulset.rollingUpdatePartition` are merged into `updateStrategy`. + - `securityContext.*` is deprecated in favor of `podSecurityContext` and `containerSecurityContext`. + - `configFileConfigMap` is deprecated in favor of `configuration` and `existingConfigmap`. + - `envVarsConfigMap` is deprecated in favor of `extraEnvVars`, `extraEnvVarsCM` and `extraEnvVarsSecret`. + - `allowNoneAuthentication` is renamed to `auth.rbac.allowNoneAuthentication`. +- New parameters/features were added: + - `extraDeploy` to deploy any extra desired object. + - `initContainers` and `sidecars` to define custom init containers and sidecars. + - `extraVolumes`, `extraVolumeMounts` and `extraVolumeClaimTemplates` to define custom volumes, mount points and volume claim templates. + - Probes can be now customized, and support to startup probes is added. + - LifecycleHooks can be customized using `lifecycleHooks` parameter. + - The default command/args can be customized using `command` and `args` parameters. +- Metrics integration with Prometheus Operator does no longer use a ServiceMonitor object, but a PodMonitor instead. + +Consequences: + +- Backwards compatibility is not guaranteed unless you adapt you **values.yaml** according to the changes described above. + +### To 5.2.0 + +This version introduces `bitnami/common`, a [library chart](https://helm.sh/docs/topics/library_charts/#helm) as a dependency. More documentation about this new utility could be found [here](https://github.com/bitnami/charts/tree/main/bitnami/common#bitnami-common-library-chart). Please, make sure that you have updated the chart dependencies before executing any upgrade. + +### To 5.0.0 + +[On November 13, 2020, Helm v2 support formally ended](https://github.com/helm/charts#status-of-the-project). This major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +### To 4.4.14 + +In this release we addressed a vulnerability that showed the `ETCD_ROOT_PASSWORD` environment variable in the application logs. Users are advised to update immediately. More information in [this issue](https://github.com/bitnami/charts/issues/1901). + +### To 3.0.0 + +Backwards compatibility is not guaranteed. The following notables changes were included: + +- **etcdctl** uses v3 API. +- Adds support for auto disaster recovery. +- Labels are adapted to follow the Helm charts best practices. + +To upgrade from previous charts versions, create a snapshot of the keyspace and restore it in a new etcd cluster. Only v3 API data can be restored. +You can use the command below to upgrade your chart by starting a new cluster using an existing snapshot, available in an existing PVC, to initialize the members: + +```console +helm install new-release oci://REGISTRY_NAME/REPOSITORY_NAME/etcd \ + --set statefulset.replicaCount=3 \ + --set persistence.enabled=true \ + --set persistence.size=8Gi \ + --set startFromSnapshot.enabled=true \ + --set startFromSnapshot.existingClaim=my-claim \ + --set startFromSnapshot.snapshotFilename=my-snapshot.db +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +### To 1.0.0 + +Backwards compatibility is not guaranteed unless you modify the labels used on the chart's deployments. +Use the workaround below to upgrade from versions previous to 1.0.0. The following example assumes that the release name is etcd: + +```console +kubectl delete statefulset etcd --cascade=false +``` + +## License + +Copyright © 2025 Broadcom. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/charts/mayastor/charts/etcd/charts/common/.helmignore b/charts/mayastor/charts/etcd/charts/common/.helmignore new file mode 100644 index 0000000..d0e1084 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/.helmignore @@ -0,0 +1,26 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +# img folder +img/ +# Changelog +CHANGELOG.md diff --git a/charts/mayastor/charts/etcd/charts/common/Chart.yaml b/charts/mayastor/charts/etcd/charts/common/Chart.yaml new file mode 100644 index 0000000..c5d6526 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/Chart.yaml @@ -0,0 +1,23 @@ +annotations: + category: Infrastructure + licenses: Apache-2.0 +apiVersion: v2 +appVersion: 2.31.1 +description: A Library Helm Chart for grouping common logic between bitnami charts. + This chart is not deployable by itself. +home: https://bitnami.com +icon: https://dyltqmyl993wv.cloudfront.net/downloads/logos/bitnami-mark.png +keywords: +- common +- helper +- template +- function +- bitnami +maintainers: +- name: Broadcom, Inc. All Rights Reserved. + url: https://github.com/bitnami/charts +name: common +sources: +- https://github.com/bitnami/charts/tree/main/bitnami/common +type: library +version: 2.31.1 diff --git a/charts/mayastor/charts/etcd/charts/common/README.md b/charts/mayastor/charts/etcd/charts/common/README.md new file mode 100644 index 0000000..b84bbba --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/README.md @@ -0,0 +1,381 @@ +# Bitnami Common Library Chart + +A [Helm Library Chart](https://helm.sh/docs/topics/library_charts/#helm) for grouping common logic between Bitnami charts. + +## TL;DR + +```yaml +dependencies: + - name: common + version: 2.x.x + repository: oci://registry-1.docker.io/bitnamicharts +``` + +```console +helm dependency update +``` + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "common.names.fullname" . }} +data: + myvalue: "Hello World" +``` + +Looking to use our applications in production? Try [VMware Tanzu Application Catalog](https://bitnami.com/enterprise), the commercial edition of the Bitnami catalog. + +## Introduction + +This chart provides a common template helpers which can be used to develop new charts using [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.23+ +- Helm 3.8.0+ + +## Parameters + +The following table lists the helpers available in the library which are scoped in different sections. + +### Affinities + +| Helper identifier | Description | Expected Input | +| ------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------ | +| `common.affinities.nodes.soft` | Return a soft nodeAffinity definition | `dict "key" "FOO" "values" (list "BAR" "BAZ")` | +| `common.affinities.nodes.hard` | Return a hard nodeAffinity definition | `dict "key" "FOO" "values" (list "BAR" "BAZ")` | +| `common.affinities.nodes` | Return a nodeAffinity definition | `dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")` | +| `common.affinities.topologyKey` | Return a topologyKey definition | `dict "topologyKey" "FOO"` | +| `common.affinities.pods.soft` | Return a soft podAffinity/podAntiAffinity definition | `dict "component" "FOO" "context" $` | +| `common.affinities.pods.hard` | Return a hard podAffinity/podAntiAffinity definition | `dict "component" "FOO" "context" $` | +| `common.affinities.pods` | Return a podAffinity/podAntiAffinity definition | `dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")` | + +### Capabilities + +| Helper identifier | Description | Expected Input | +| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------- | +| `common.capabilities.kubeVersion` | Return the target Kubernetes version (using client default if .Values.kubeVersion is not set). | `.` Chart context | +| `common.capabilities.apiVersions.has` | Return true if the apiVersion is supported | `dict "version" "batch/v1" "context" $` | +| `common.capabilities.job.apiVersion` | Return the appropriate apiVersion for job. | `.` Chart context | +| `common.capabilities.cronjob.apiVersion` | Return the appropriate apiVersion for cronjob. | `.` Chart context | +| `common.capabilities.daemonset.apiVersion` | Return the appropriate apiVersion for daemonset. | `.` Chart context | +| `common.capabilities.cronjob.apiVersion` | Return the appropriate apiVersion for cronjob. | `.` Chart context | +| `common.capabilities.deployment.apiVersion` | Return the appropriate apiVersion for deployment. | `.` Chart context | +| `common.capabilities.statefulset.apiVersion` | Return the appropriate apiVersion for statefulset. | `.` Chart context | +| `common.capabilities.ingress.apiVersion` | Return the appropriate apiVersion for ingress. | `.` Chart context | +| `common.capabilities.rbac.apiVersion` | Return the appropriate apiVersion for RBAC resources. | `.` Chart context | +| `common.capabilities.crd.apiVersion` | Return the appropriate apiVersion for CRDs. | `.` Chart context | +| `common.capabilities.policy.apiVersion` | Return the appropriate apiVersion for podsecuritypolicy. | `.` Chart context | +| `common.capabilities.networkPolicy.apiVersion` | Return the appropriate apiVersion for networkpolicy. | `.` Chart context | +| `common.capabilities.apiService.apiVersion` | Return the appropriate apiVersion for APIService. | `.` Chart context | +| `common.capabilities.hpa.apiVersion` | Return the appropriate apiVersion for Horizontal Pod Autoscaler | `.` Chart context | +| `common.capabilities.vpa.apiVersion` | Return the appropriate apiVersion for Vertical Pod Autoscaler. | `.` Chart context | +| `common.capabilities.psp.supported` | Returns true if PodSecurityPolicy is supported | `.` Chart context | +| `common.capabilities.supportsHelmVersion` | Returns true if the used Helm version is 3.3+ | `.` Chart context | +| `common.capabilities.admissionConfiguration.supported` | Returns true if AdmissionConfiguration is supported | `.` Chart context | +| `common.capabilities.admissionConfiguration.apiVersion` | Return the appropriate apiVersion for AdmissionConfiguration. | `.` Chart context | +| `common.capabilities.podSecurityConfiguration.apiVersion` | Return the appropriate apiVersion for PodSecurityConfiguration. | `.` Chart context | + +### Compatibility + +| Helper identifier | Description | Expected Input | +| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | +| `common.compatibility.isOpenshift` | Return true if the detected platform is Openshift | `.` Chart context | +| `common.compatibility.renderSecurityContext` | Render a compatible securityContext depending on the platform. By default it is maintained as it is. In other platforms like Openshift we remove default user/group values that do not work out of the box with the restricted-v1 SCC | `dict "secContext" .Values.containerSecurityContext "context" $` | + +### Errors + +| Helper identifier | Description | Expected Input | +| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | +| `common.errors.upgrade.passwords.empty` | It will ensure required passwords are given when we are upgrading a chart. If `validationErrors` is not empty it will throw an error and will stop the upgrade action. | `dict "validationErrors" (list $validationError00 $validationError01) "context" $` | +| `common.errors.insecureImages` | Throw error when original container images are replaced. The error can be bypassed by setting the `global.security.allowInsecureImages` to true. | `dict "images" (list .Values.path.to.the.imageRoot) "context" $` | + +### Images + +| Helper identifier | Description | Expected Input | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `common.images.image` | Return the proper and full image name | `dict "imageRoot" .Values.path.to.the.image "global" $`, see [ImageRoot](#imageroot) for the structure. | +| `common.images.pullSecrets` | Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) | `dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global` | +| `common.images.renderPullSecrets` | Return the proper Docker Image Registry Secret Names (evaluates values as templates) | `dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $` | +| `common.images.version` | Return the proper image version | `dict "imageRoot" .Values.path.to.the.image "chart" .Chart` , see [ImageRoot](#imageroot) for the structure. | + +### Ingress + +| Helper identifier | Description | Expected Input | +| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `common.ingress.backend` | Generate a proper Ingress backend entry depending on the API version | `dict "serviceName" "foo" "servicePort" "bar"`, see the [Ingress deprecation notice](https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/) for the syntax differences | +| `common.ingress.supportsPathType` | Prints "true" if the pathType field is supported | `.` Chart context | +| `common.ingress.supportsIngressClassname` | Prints "true" if the ingressClassname field is supported | `.` Chart context | +| `common.ingress.certManagerRequest` | Prints "true" if required cert-manager annotations for TLS signed certificates are set in the Ingress annotations | `dict "annotations" .Values.path.to.the.ingress.annotations` | + +### Labels + +| Helper identifier | Description | Expected Input | +| --------------------------- | --------------------------------------------------------------------------- | ----------------- | +| `common.labels.standard` | Return Kubernetes standard labels | `.` Chart context | +| `common.labels.matchLabels` | Labels to use on `deploy.spec.selector.matchLabels` and `svc.spec.selector` | `.` Chart context | + +### Names + +| Helper identifier | Description | Expected Input | +| ---------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| `common.names.name` | Expand the name of the chart or use `.Values.nameOverride` | `.` Chart context | +| `common.names.fullname` | Create a default fully qualified app name. | `.` Chart context | +| `common.names.namespace` | Allow the release namespace to be overridden | `.` Chart context | +| `common.names.fullname.namespace` | Create a fully qualified app name adding the installation's namespace | `.` Chart context | +| `common.names.chart` | Chart name plus version | `.` Chart context | +| `common.names.dependency.fullname` | Create a default fully qualified dependency name. | `dict "chartName" "dependency-chart-name" "chartValues" .Values.dependency-chart "context" $` | + +### Resources + +| Helper identifier | Description | Expected Input | +| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| `common.resources.preset` | Return a resource request/limit object based on a given preset. These presets are for basic testing and not meant to be used in production. | `dict "type" "nano"` | + +### Secrets + +| Helper identifier | Description | Expected Input | +| --------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `common.secrets.name` | Generate the name of the secret. | `dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $` see [ExistingSecret](#existingsecret) for the structure. | +| `common.secrets.key` | Generate secret key. | `dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName"` see [ExistingSecret](#existingsecret) for the structure. | +| `common.secrets.passwords.manage` | Generate secret password or retrieve one if already created. | `dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "honorProvidedValues" false "context" $`, length, strong, honorProvidedValues and chartName fields are optional. | +| `common.secrets.exists` | Returns whether a previous generated secret already exists. | `dict "secret" "secret-name" "context" $` | +| `common.secrets.lookup` | Reuses the value from an existing secret, otherwise sets its value to a default value. | `dict "secret" "secret-name" "key" "keyName" "defaultValue" .Values.myValue "context" $` | + +### Storage + +| Helper identifier | Description | Expected Input | +| ---------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------- | +| `common.storage.class` | Return the proper Storage Class | `dict "persistence" .Values.path.to.the.persistence "global" $`, see [Persistence](#persistence) for the structure. | + +### TplValues + +| Helper identifier | Description | Expected Input | +| ---------------------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `common.tplvalues.render` | Renders a value that contains template | `dict "value" .Values.path.to.the.Value "context" $`, value is the value should rendered as template, context frequently is the chart context `$` or `.` | +| `common.tplvalues.merge` | Merge a list of values that contains template after rendering them. | `dict "values" (list .Values.path.to.the.Value1 .Values.path.to.the.Value2) "context" $` | +| `common.tplvalues.merge-overwrite` | Merge a list of values that contains template after rendering them. | `dict "values" (list .Values.path.to.the.Value1 .Values.path.to.the.Value2) "context" $` | + +### Utils + +| Helper identifier | Description | Expected Input | +| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| `common.utils.fieldToEnvVar` | Build environment variable name given a field. | `dict "field" "my-password"` | +| `common.utils.secret.getvalue` | Print instructions to get a secret value. | `dict "secret" "secret-name" "field" "secret-value-field" "context" $` | +| `common.utils.getValueFromKey` | Gets a value from `.Values` object given its key path | `dict "key" "path.to.key" "context" $` | +| `common.utils.getKeyFromList` | Returns first `.Values` key with a defined value or first of the list if all non-defined | `dict "keys" (list "path.to.key1" "path.to.key2") "context" $` | +| `common.utils.checksumTemplate` | Checksum a template at "path" containing a *single* resource (ConfigMap,Secret) for use in pod annotations, excluding the metadata (see #18376) | `dict "path" "/configmap.yaml" "context" $` | + +### Validations + +| Helper identifier | Description | Expected Input | +| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `common.validations.values.single.empty` | Validate a value must not be empty. | `dict "valueKey" "path.to.value" "secret" "secret.name" "field" "my-password" "subchart" "subchart" "context" $` secret, field and subchart are optional. In case they are given, the helper will generate a how to get instruction. See [ValidateValue](#validatevalue) | +| `common.validations.values.multiple.empty` | Validate a multiple values must not be empty. It returns a shared error for all the values. | `dict "required" (list $validateValueConf00 $validateValueConf01) "context" $`. See [ValidateValue](#validatevalue) | +| `common.validations.values.mariadb.passwords` | This helper will ensure required password for MariaDB are not empty. It returns a shared error for all the values. | `dict "secret" "mariadb-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use mariadb chart and the helper. | + +### Warnings + +| Helper identifier | Description | Expected Input | +| -------------------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------- | +| `common.warnings.rollingTag` | Warning about using rolling tag. | `ImageRoot` see [ImageRoot](#imageroot) for the structure. | +| `common.warnings.modifiedImages` | Warning about replaced images from the original. | `ImageRoot` see [ImageRoot](#imageroot) for the structure. | +| `common.warnings.resources` | Warning about not setting the resource object in all deployments. | `dict "sections" (list "path1" "path2") context $` | + +## Special input schemas + +### ImageRoot + +```yaml +registry: + type: string + description: Docker registry where the image is located + example: docker.io + +repository: + type: string + description: Repository and image name + example: bitnami/nginx + +tag: + type: string + description: image tag + example: 1.16.1-debian-10-r63 + +pullPolicy: + type: string + description: Specify a imagePullPolicy.' + +pullSecrets: + type: array + items: + type: string + description: Optionally specify an array of imagePullSecrets (evaluated as templates). + +debug: + type: boolean + description: Set to true if you would like to see extra information on logs + example: false + +## An instance would be: +# registry: docker.io +# repository: bitnami/nginx +# tag: 1.16.1-debian-10-r63 +# pullPolicy: IfNotPresent +# debug: false +``` + +### Persistence + +```yaml +enabled: + type: boolean + description: Whether enable persistence. + example: true + +storageClass: + type: string + description: Ghost data Persistent Volume Storage Class, If set to "-", storageClassName: "" which disables dynamic provisioning. + example: "-" + +accessMode: + type: string + description: Access mode for the Persistent Volume Storage. + example: ReadWriteOnce + +size: + type: string + description: Size the Persistent Volume Storage. + example: 8Gi + +path: + type: string + description: Path to be persisted. + example: /bitnami + +## An instance would be: +# enabled: true +# storageClass: "-" +# accessMode: ReadWriteOnce +# size: 8Gi +# path: /bitnami +``` + +### ExistingSecret + +```yaml +name: + type: string + description: Name of the existing secret. + example: mySecret +keyMapping: + description: Mapping between the expected key name and the name of the key in the existing secret. + type: object + +## An instance would be: +# name: mySecret +# keyMapping: +# password: myPasswordKey +``` + +#### Example of use + +When we store sensitive data for a deployment in a secret, some times we want to give to users the possibility of using theirs existing secrets. + +```yaml +# templates/secret.yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + labels: + app: {{ include "common.names.fullname" . }} +type: Opaque +data: + password: {{ .Values.password | b64enc | quote }} + +# templates/dpl.yaml +--- +... + env: + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "context" $) }} + key: {{ include "common.secrets.key" (dict "existingSecret" .Values.existingSecret "key" "password") }} +... + +# values.yaml +--- +name: mySecret +keyMapping: + password: myPasswordKey +``` + +### ValidateValue + +#### NOTES.txt + +```console +{{- $validateValueConf00 := (dict "valueKey" "path.to.value00" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value01" "secret" "secretName" "field" "password-01") -}} + +{{ include "common.validations.values.multiple.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} +``` + +If we force those values to be empty we will see some alerts + +```console +helm install test mychart --set path.to.value00="",path.to.value01="" + 'path.to.value00' must not be empty, please add '--set path.to.value00=$PASSWORD_00' to the command. To get the current value: + + export PASSWORD_00=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-00}" | base64 -d) + + 'path.to.value01' must not be empty, please add '--set path.to.value01=$PASSWORD_01' to the command. To get the current value: + + export PASSWORD_01=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-01}" | base64 -d) +``` + +## Upgrading + +### To 1.0.0 + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +#### What changes were introduced in this major version? + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- Use `type: library`. [Here](https://v3.helm.sh/docs/faq/#library-chart-support) you can find more information. +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Charts + +#### Considerations when upgrading to this version + +- If you want to upgrade to this version from a previous one installed with Helm v3, you shouldn't face any issues +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +#### Useful links + +- +- +- + +## License + +Copyright © 2025 Broadcom. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_affinities.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_affinities.tpl new file mode 100644 index 0000000..c6ccc62 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_affinities.tpl @@ -0,0 +1,169 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return a soft nodeAffinity definition +{{ include "common.affinities.nodes.soft" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.soft" -}} +preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} + weight: 1 +{{- end -}} + +{{/* +Return a hard nodeAffinity definition +{{ include "common.affinities.nodes.hard" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.hard" -}} +requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} +{{- end -}} + +{{/* +Return a nodeAffinity definition +{{ include "common.affinities.nodes" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.nodes.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.nodes.hard" . -}} + {{- end -}} +{{- end -}} + +{{/* +Return a topologyKey definition +{{ include "common.affinities.topologyKey" (dict "topologyKey" "BAR") -}} +*/}} +{{- define "common.affinities.topologyKey" -}} +{{ .topologyKey | default "kubernetes.io/hostname" -}} +{{- end -}} + +{{/* +Return a soft podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods.soft" (dict "component" "FOO" "customLabels" .Values.podLabels "extraMatchLabels" .Values.extraMatchLabels "topologyKey" "BAR" "extraPodAffinityTerms" .Values.extraPodAffinityTerms "extraNamespaces" (list "namespace1" "namespace2") "context" $) -}} +*/}} +{{- define "common.affinities.pods.soft" -}} +{{- $component := default "" .component -}} +{{- $customLabels := default (dict) .customLabels -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +{{- $extraPodAffinityTerms := default (list) .extraPodAffinityTerms -}} +{{- $extraNamespaces := default (list) .extraNamespaces -}} +preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" ( dict "customLabels" $customLabels "context" .context )) | nindent 10 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if $extraNamespaces }} + namespaces: + - {{ .context.Release.Namespace }} + {{- with $extraNamespaces }} + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 8 }} + {{- end }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} + weight: 1 + {{- range $extraPodAffinityTerms }} + - podAffinityTerm: + labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" ( dict "customLabels" $customLabels "context" $.context )) | nindent 10 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := .extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if .namespaces }} + namespaces: + - {{ $.context.Release.Namespace }} + {{- with .namespaces }} + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 8 }} + {{- end }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} + weight: {{ .weight | default 1 -}} + {{- end -}} +{{- end -}} + +{{/* +Return a hard podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods.hard" (dict "component" "FOO" "customLabels" .Values.podLabels "extraMatchLabels" .Values.extraMatchLabels "topologyKey" "BAR" "extraPodAffinityTerms" .Values.extraPodAffinityTerms "extraNamespaces" (list "namespace1" "namespace2") "context" $) -}} +*/}} +{{- define "common.affinities.pods.hard" -}} +{{- $component := default "" .component -}} +{{- $customLabels := default (dict) .customLabels -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +{{- $extraPodAffinityTerms := default (list) .extraPodAffinityTerms -}} +{{- $extraNamespaces := default (list) .extraNamespaces -}} +requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" ( dict "customLabels" $customLabels "context" .context )) | nindent 8 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if $extraNamespaces }} + namespaces: + - {{ .context.Release.Namespace }} + {{- with $extraNamespaces }} + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 6 }} + {{- end }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} + {{- range $extraPodAffinityTerms }} + - labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" ( dict "customLabels" $customLabels "context" $.context )) | nindent 8 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := .extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if .namespaces }} + namespaces: + - {{ $.context.Release.Namespace }} + {{- with .namespaces }} + {{- include "common.tplvalues.render" (dict "value" . "context" $) | nindent 6 }} + {{- end }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} + {{- end -}} +{{- end -}} + +{{/* +Return a podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.pods" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.pods.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.pods.hard" . -}} + {{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_capabilities.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_capabilities.tpl new file mode 100644 index 0000000..6efde9d --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_capabilities.tpl @@ -0,0 +1,178 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return the target Kubernetes version +*/}} +{{- define "common.capabilities.kubeVersion" -}} +{{- default (default .Capabilities.KubeVersion.Version .Values.kubeVersion) ((.Values.global).kubeVersion) -}} +{{- end -}} + +{{/* +Return true if the apiVersion is supported +Usage: +{{ include "common.capabilities.apiVersions.has" (dict "version" "batch/v1" "context" $) }} +*/}} +{{- define "common.capabilities.apiVersions.has" -}} +{{- $providedAPIVersions := default .context.Values.apiVersions ((.context.Values.global).apiVersions) -}} +{{- if and (empty $providedAPIVersions) (.context.Capabilities.APIVersions.Has .version) -}} + {{- true -}} +{{- else if has .version $providedAPIVersions -}} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for poddisruptionbudget. +*/}} +{{- define "common.capabilities.policy.apiVersion" -}} +{{- print "policy/v1" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "common.capabilities.networkPolicy.apiVersion" -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for job. +*/}} +{{- define "common.capabilities.job.apiVersion" -}} +{{- print "batch/v1" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for cronjob. +*/}} +{{- define "common.capabilities.cronjob.apiVersion" -}} +{{- print "batch/v1" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for daemonset. +*/}} +{{- define "common.capabilities.daemonset.apiVersion" -}} +{{- print "apps/v1" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for deployment. +*/}} +{{- define "common.capabilities.deployment.apiVersion" -}} +{{- print "apps/v1" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for statefulset. +*/}} +{{- define "common.capabilities.statefulset.apiVersion" -}} +{{- print "apps/v1" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "common.capabilities.ingress.apiVersion" -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for RBAC resources. +*/}} +{{- define "common.capabilities.rbac.apiVersion" -}} +{{- print "rbac.authorization.k8s.io/v1" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for CRDs. +*/}} +{{- define "common.capabilities.crd.apiVersion" -}} +{{- print "apiextensions.k8s.io/v1" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for APIService. +*/}} +{{- define "common.capabilities.apiService.apiVersion" -}} +{{- print "apiregistration.k8s.io/v1" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for Horizontal Pod Autoscaler. +*/}} +{{- define "common.capabilities.hpa.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" .context -}} +{{- print "autoscaling/v2" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for Vertical Pod Autoscaler. +*/}} +{{- define "common.capabilities.vpa.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" .context -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.25-0" $kubeVersion) -}} +{{- print "autoscaling/v1beta2" -}} +{{- else -}} +{{- print "autoscaling/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if PodSecurityPolicy is supported +*/}} +{{- define "common.capabilities.psp.supported" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if or (empty $kubeVersion) (semverCompare "<1.25-0" $kubeVersion) -}} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if AdmissionConfiguration is supported +*/}} +{{- define "common.capabilities.admissionConfiguration.supported" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} + {{- true -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for AdmissionConfiguration. +*/}} +{{- define "common.capabilities.admissionConfiguration.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.25-0" $kubeVersion) -}} +{{- print "apiserver.config.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiserver.config.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for PodSecurityConfiguration. +*/}} +{{- define "common.capabilities.podSecurityConfiguration.apiVersion" -}} +{{- $kubeVersion := include "common.capabilities.kubeVersion" . -}} +{{- if and (not (empty $kubeVersion)) (semverCompare "<1.25-0" $kubeVersion) -}} +{{- print "pod-security.admission.config.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "pod-security.admission.config.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the used Helm version is 3.3+. +A way to check the used Helm version was not introduced until version 3.3.0 with .Capabilities.HelmVersion, which contains an additional "{}}" structure. +This check is introduced as a regexMatch instead of {{ if .Capabilities.HelmVersion }} because checking for the key HelmVersion in <3.3 results in a "interface not found" error. +**To be removed when the catalog's minimun Helm version is 3.3** +*/}} +{{- define "common.capabilities.supportsHelmVersion" -}} +{{- if regexMatch "{(v[0-9])*[^}]*}}$" (.Capabilities | toString ) }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_compatibility.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_compatibility.tpl new file mode 100644 index 0000000..19c26db --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_compatibility.tpl @@ -0,0 +1,46 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return true if the detected platform is Openshift +Usage: +{{- include "common.compatibility.isOpenshift" . -}} +*/}} +{{- define "common.compatibility.isOpenshift" -}} +{{- if .Capabilities.APIVersions.Has "security.openshift.io/v1" -}} +{{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Render a compatible securityContext depending on the platform. By default it is maintained as it is. In other platforms like Openshift we remove default user/group values that do not work out of the box with the restricted-v1 SCC +Usage: +{{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) -}} +*/}} +{{- define "common.compatibility.renderSecurityContext" -}} +{{- $adaptedContext := .secContext -}} + +{{- if (((.context.Values.global).compatibility).openshift) -}} + {{- if or (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "force") (and (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "auto") (include "common.compatibility.isOpenshift" .context)) -}} + {{/* Remove incompatible user/group values that do not work in Openshift out of the box */}} + {{- $adaptedContext = omit $adaptedContext "fsGroup" "runAsUser" "runAsGroup" -}} + {{- if not .secContext.seLinuxOptions -}} + {{/* If it is an empty object, we remove it from the resulting context because it causes validation issues */}} + {{- $adaptedContext = omit $adaptedContext "seLinuxOptions" -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{/* Remove empty seLinuxOptions object if global.compatibility.omitEmptySeLinuxOptions is set to true */}} +{{- if and (((.context.Values.global).compatibility).omitEmptySeLinuxOptions) (not .secContext.seLinuxOptions) -}} + {{- $adaptedContext = omit $adaptedContext "seLinuxOptions" -}} +{{- end -}} +{{/* Remove fields that are disregarded when running the container in privileged mode */}} +{{- if $adaptedContext.privileged -}} + {{- $adaptedContext = omit $adaptedContext "capabilities" -}} +{{- end -}} +{{- omit $adaptedContext "enabled" | toYaml -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_errors.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_errors.tpl new file mode 100644 index 0000000..95b8b8e --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_errors.tpl @@ -0,0 +1,85 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Throw error when upgrading using empty passwords values that must not be empty. + +Usage: +{{- $validationError00 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password00" "secret" "secretName" "field" "password-00") -}} +{{- $validationError01 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password01" "secret" "secretName" "field" "password-01") -}} +{{ include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $validationError00 $validationError01) "context" $) }} + +Required password params: + - validationErrors - String - Required. List of validation strings to be return, if it is empty it won't throw error. + - context - Context - Required. Parent context. +*/}} +{{- define "common.errors.upgrade.passwords.empty" -}} + {{- $validationErrors := join "" .validationErrors -}} + {{- if and $validationErrors .context.Release.IsUpgrade -}} + {{- $errorString := "\nPASSWORDS ERROR: You must provide your current passwords when upgrading the release." -}} + {{- $errorString = print $errorString "\n Note that even after reinstallation, old credentials may be needed as they may be kept in persistent volume claims." -}} + {{- $errorString = print $errorString "\n Further information can be obtained at https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues/#credential-errors-while-upgrading-chart-releases" -}} + {{- $errorString = print $errorString "\n%s" -}} + {{- printf $errorString $validationErrors | fail -}} + {{- end -}} +{{- end -}} + +{{/* +Throw error when original container images are replaced. +The error can be bypassed by setting the "global.security.allowInsecureImages" to true. In this case, +a warning message will be shown instead. + +Usage: +{{ include "common.errors.insecureImages" (dict "images" (list .Values.path.to.the.imageRoot) "context" $) }} +*/}} +{{- define "common.errors.insecureImages" -}} +{{- $relocatedImages := list -}} +{{- $replacedImages := list -}} +{{- $retaggedImages := list -}} +{{- $globalRegistry := ((.context.Values.global).imageRegistry) -}} +{{- $originalImages := .context.Chart.Annotations.images -}} +{{- range .images -}} + {{- $registryName := default .registry $globalRegistry -}} + {{- $fullImageNameNoTag := printf "%s/%s" $registryName .repository -}} + {{- $fullImageName := printf "%s:%s" $fullImageNameNoTag .tag -}} + {{- if not (contains $fullImageNameNoTag $originalImages) -}} + {{- if not (contains $registryName $originalImages) -}} + {{- $relocatedImages = append $relocatedImages $fullImageName -}} + {{- else if not (contains .repository $originalImages) -}} + {{- $replacedImages = append $replacedImages $fullImageName -}} + {{- end -}} + {{- end -}} + {{- if not (contains (printf "%s:%s" .repository .tag) $originalImages) -}} + {{- $retaggedImages = append $retaggedImages $fullImageName -}} + {{- end -}} +{{- end -}} + +{{- if and (or (gt (len $relocatedImages) 0) (gt (len $replacedImages) 0)) (((.context.Values.global).security).allowInsecureImages) -}} + {{- print "\n\n⚠ SECURITY WARNING: Verifying original container images was skipped. Please note this Helm chart was designed, tested, and validated on multiple platforms using a specific set of Bitnami and Tanzu Application Catalog containers. Substituting other containers is likely to cause degraded security and performance, broken chart features, and missing environment variables.\n" -}} +{{- else if (or (gt (len $relocatedImages) 0) (gt (len $replacedImages) 0)) -}} + {{- $errorString := "Original containers have been substituted for unrecognized ones. Deploying this chart with non-standard containers is likely to cause degraded security and performance, broken chart features, and missing environment variables." -}} + {{- $errorString = print $errorString "\n\nUnrecognized images:" -}} + {{- range (concat $relocatedImages $replacedImages) -}} + {{- $errorString = print $errorString "\n - " . -}} + {{- end -}} + {{- if or (contains "docker.io/bitnami/" $originalImages) (contains "docker.io/bitnamiprem/" $originalImages) -}} + {{- $errorString = print "\n\n⚠ ERROR: " $errorString -}} + {{- $errorString = print $errorString "\n\nIf you are sure you want to proceed with non-standard containers, you can skip container image verification by setting the global parameter 'global.security.allowInsecureImages' to true." -}} + {{- $errorString = print $errorString "\nFurther information can be obtained at https://github.com/bitnami/charts/issues/30850" -}} + {{- print $errorString | fail -}} + {{- else if gt (len $replacedImages) 0 -}} + {{- $errorString = print "\n\n⚠ WARNING: " $errorString -}} + {{- print $errorString -}} + {{- end -}} +{{- else if gt (len $retaggedImages) 0 -}} + {{- $warnString := "\n\n⚠ WARNING: Original containers have been retagged. Please note this Helm chart was tested, and validated on multiple platforms using a specific set of Tanzu Application Catalog containers. Substituting original image tags could cause unexpected behavior." -}} + {{- $warnString = print $warnString "\n\nRetagged images:" -}} + {{- range $retaggedImages -}} + {{- $warnString = print $warnString "\n - " . -}} + {{- end -}} + {{- print $warnString -}} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_images.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_images.tpl new file mode 100644 index 0000000..76bb7ce --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_images.tpl @@ -0,0 +1,115 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Return the proper image name. +If image tag and digest are not defined, termination fallbacks to chart appVersion. +{{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" .Values.global "chart" .Chart ) }} +*/}} +{{- define "common.images.image" -}} +{{- $registryName := default .imageRoot.registry ((.global).imageRegistry) -}} +{{- $repositoryName := .imageRoot.repository -}} +{{- $separator := ":" -}} +{{- $termination := .imageRoot.tag | toString -}} + +{{- if not .imageRoot.tag }} + {{- if .chart }} + {{- $termination = .chart.AppVersion | toString -}} + {{- end -}} +{{- end -}} +{{- if .imageRoot.digest }} + {{- $separator = "@" -}} + {{- $termination = .imageRoot.digest | toString -}} +{{- end -}} +{{- if $registryName }} + {{- printf "%s/%s%s%s" $registryName $repositoryName $separator $termination -}} +{{- else -}} + {{- printf "%s%s%s" $repositoryName $separator $termination -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) +{{ include "common.images.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global) }} +*/}} +{{- define "common.images.pullSecrets" -}} + {{- $pullSecrets := list }} + + {{- range ((.global).imagePullSecrets) -}} + {{- if kindIs "map" . -}} + {{- $pullSecrets = append $pullSecrets .name -}} + {{- else -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end }} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- if kindIs "map" . -}} + {{- $pullSecrets = append $pullSecrets .name -}} + {{- else -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) -}} +imagePullSecrets: + {{- range $pullSecrets | uniq }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names evaluating values as templates +{{ include "common.images.renderPullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $) }} +*/}} +{{- define "common.images.renderPullSecrets" -}} + {{- $pullSecrets := list }} + {{- $context := .context }} + + {{- range (($context.Values.global).imagePullSecrets) -}} + {{- if kindIs "map" . -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" $context)) -}} + {{- else -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- if kindIs "map" . -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" .name "context" $context)) -}} + {{- else -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) -}} +imagePullSecrets: + {{- range $pullSecrets | uniq }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Return the proper image version (ingores image revision/prerelease info & fallbacks to chart appVersion) +{{ include "common.images.version" ( dict "imageRoot" .Values.path.to.the.image "chart" .Chart ) }} +*/}} +{{- define "common.images.version" -}} +{{- $imageTag := .imageRoot.tag | toString -}} +{{/* regexp from https://github.com/Masterminds/semver/blob/23f51de38a0866c5ef0bfc42b3f735c73107b700/version.go#L41-L44 */}} +{{- if regexMatch `^([0-9]+)(\.[0-9]+)?(\.[0-9]+)?(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?$` $imageTag -}} + {{- $version := semver $imageTag -}} + {{- printf "%d.%d.%d" $version.Major $version.Minor $version.Patch -}} +{{- else -}} + {{- print .chart.AppVersion -}} +{{- end -}} +{{- end -}} + diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_ingress.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_ingress.tpl new file mode 100644 index 0000000..2d0dbf1 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_ingress.tpl @@ -0,0 +1,41 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Generate backend entry that is compatible with all Kubernetes API versions. + +Usage: +{{ include "common.ingress.backend" (dict "serviceName" "backendName" "servicePort" "backendPort" "context" $) }} + +Params: + - serviceName - String. Name of an existing service backend + - servicePort - String/Int. Port name (or number) of the service. It will be translated to different yaml depending if it is a string or an integer. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.ingress.backend" -}} +service: + name: {{ .serviceName }} + port: + {{- if typeIs "string" .servicePort }} + name: {{ .servicePort }} + {{- else if or (typeIs "int" .servicePort) (typeIs "float64" .servicePort) }} + number: {{ .servicePort | int }} + {{- end }} +{{- end -}} + +{{/* +Return true if cert-manager required annotations for TLS signed +certificates are set in the Ingress annotations +Ref: https://cert-manager.io/docs/usage/ingress/#supported-annotations +Usage: +{{ include "common.ingress.certManagerRequest" ( dict "annotations" .Values.path.to.the.ingress.annotations ) }} +*/}} +{{- define "common.ingress.certManagerRequest" -}} +{{ if or (hasKey .annotations "cert-manager.io/cluster-issuer") (hasKey .annotations "cert-manager.io/issuer") (hasKey .annotations "kubernetes.io/tls-acme") }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_labels.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_labels.tpl new file mode 100644 index 0000000..0a0cc54 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_labels.tpl @@ -0,0 +1,46 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Kubernetes standard labels +{{ include "common.labels.standard" (dict "customLabels" .Values.commonLabels "context" $) -}} +*/}} +{{- define "common.labels.standard" -}} +{{- if and (hasKey . "customLabels") (hasKey . "context") -}} +{{- $default := dict "app.kubernetes.io/name" (include "common.names.name" .context) "helm.sh/chart" (include "common.names.chart" .context) "app.kubernetes.io/instance" .context.Release.Name "app.kubernetes.io/managed-by" .context.Release.Service -}} +{{- with .context.Chart.AppVersion -}} +{{- $_ := set $default "app.kubernetes.io/version" . -}} +{{- end -}} +{{ template "common.tplvalues.merge" (dict "values" (list .customLabels $default) "context" .context) }} +{{- else -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +helm.sh/chart: {{ include "common.names.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- with .Chart.AppVersion }} +app.kubernetes.io/version: {{ . | quote }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Labels used on immutable fields such as deploy.spec.selector.matchLabels or svc.spec.selector +{{ include "common.labels.matchLabels" (dict "customLabels" .Values.podLabels "context" $) -}} + +We don't want to loop over custom labels appending them to the selector +since it's very likely that it will break deployments, services, etc. +However, it's important to overwrite the standard labels if the user +overwrote them on metadata.labels fields. +*/}} +{{- define "common.labels.matchLabels" -}} +{{- if and (hasKey . "customLabels") (hasKey . "context") -}} +{{ merge (pick (include "common.tplvalues.render" (dict "value" .customLabels "context" .context) | fromYaml) "app.kubernetes.io/name" "app.kubernetes.io/instance") (dict "app.kubernetes.io/name" (include "common.names.name" .context) "app.kubernetes.io/instance" .context.Release.Name ) | toYaml }} +{{- else -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_names.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_names.tpl new file mode 100644 index 0000000..ba83956 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_names.tpl @@ -0,0 +1,71 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "common.names.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "common.names.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +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 "common.names.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified dependency 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. +Usage: +{{ include "common.names.dependency.fullname" (dict "chartName" "dependency-chart-name" "chartValues" .Values.dependency-chart "context" $) }} +*/}} +{{- define "common.names.dependency.fullname" -}} +{{- if .chartValues.fullnameOverride -}} +{{- .chartValues.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .chartName .chartValues.nameOverride -}} +{{- if contains $name .context.Release.Name -}} +{{- .context.Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .context.Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts. +*/}} +{{- define "common.names.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a fully qualified app name adding the installation's namespace. +*/}} +{{- define "common.names.fullname.namespace" -}} +{{- printf "%s-%s" (include "common.names.fullname" .) (include "common.names.namespace" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_resources.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_resources.tpl new file mode 100644 index 0000000..d8a43e1 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_resources.tpl @@ -0,0 +1,50 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return a resource request/limit object based on a given preset. +These presets are for basic testing and not meant to be used in production +{{ include "common.resources.preset" (dict "type" "nano") -}} +*/}} +{{- define "common.resources.preset" -}} +{{/* The limits are the requests increased by 50% (except ephemeral-storage and xlarge/2xlarge sizes)*/}} +{{- $presets := dict + "nano" (dict + "requests" (dict "cpu" "100m" "memory" "128Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "150m" "memory" "192Mi" "ephemeral-storage" "2Gi") + ) + "micro" (dict + "requests" (dict "cpu" "250m" "memory" "256Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "375m" "memory" "384Mi" "ephemeral-storage" "2Gi") + ) + "small" (dict + "requests" (dict "cpu" "500m" "memory" "512Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "750m" "memory" "768Mi" "ephemeral-storage" "2Gi") + ) + "medium" (dict + "requests" (dict "cpu" "500m" "memory" "1024Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "750m" "memory" "1536Mi" "ephemeral-storage" "2Gi") + ) + "large" (dict + "requests" (dict "cpu" "1.0" "memory" "2048Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "1.5" "memory" "3072Mi" "ephemeral-storage" "2Gi") + ) + "xlarge" (dict + "requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "3.0" "memory" "6144Mi" "ephemeral-storage" "2Gi") + ) + "2xlarge" (dict + "requests" (dict "cpu" "1.0" "memory" "3072Mi" "ephemeral-storage" "50Mi") + "limits" (dict "cpu" "6.0" "memory" "12288Mi" "ephemeral-storage" "2Gi") + ) + }} +{{- if hasKey $presets .type -}} +{{- index $presets .type | toYaml -}} +{{- else -}} +{{- printf "ERROR: Preset key '%s' invalid. Allowed values are %s" .type (join "," (keys $presets)) | fail -}} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_secrets.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_secrets.tpl new file mode 100644 index 0000000..7868c00 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_secrets.tpl @@ -0,0 +1,192 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Generate secret name. + +Usage: +{{ include "common.secrets.name" (dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $) }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - defaultNameSuffix - String - Optional. It is used only if we have several secrets in the same deployment. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.secrets.name" -}} +{{- $name := (include "common.names.fullname" .context) -}} + +{{- if .defaultNameSuffix -}} +{{- $name = printf "%s-%s" $name .defaultNameSuffix | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- with .existingSecret -}} +{{- if not (typeIs "string" .) -}} +{{- with .name -}} +{{- $name = . -}} +{{- end -}} +{{- else -}} +{{- $name = . -}} +{{- end -}} +{{- end -}} + +{{- printf "%s" $name -}} +{{- end -}} + +{{/* +Generate secret key. + +Usage: +{{ include "common.secrets.key" (dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName") }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - key - String - Required. Name of the key in the secret. +*/}} +{{- define "common.secrets.key" -}} +{{- $key := .key -}} + +{{- if .existingSecret -}} + {{- if not (typeIs "string" .existingSecret) -}} + {{- if .existingSecret.keyMapping -}} + {{- $key = index .existingSecret.keyMapping $.key -}} + {{- end -}} + {{- end }} +{{- end -}} + +{{- printf "%s" $key -}} +{{- end -}} + +{{/* +Generate secret password or retrieve one if already created. + +Usage: +{{ include "common.secrets.passwords.manage" (dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "honorProvidedValues" false "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - providedValues - List - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - length - int - Optional - Length of the generated random password. + - strong - Boolean - Optional - Whether to add symbols to the generated random password. + - chartName - String - Optional - Name of the chart used when said chart is deployed as a subchart. + - context - Context - Required - Parent context. + - failOnNew - Boolean - Optional - Default to true. If set to false, skip errors adding new keys to existing secrets. + - skipB64enc - Boolean - Optional - Default to false. If set to true, no the secret will not be base64 encrypted. + - skipQuote - Boolean - Optional - Default to false. If set to true, no quotes will be added around the secret. + - honorProvidedValues - Boolean - Optional - Default to false. If set to true, the values in providedValues have higher priority than an existing secret +The order in which this function returns a secret password: + 1. Password provided via the values.yaml if honorProvidedValues = true + (If one of the keys passed to the 'providedValues' parameter to this function is a valid path to a key in the values.yaml and has a value, the value of the first key with a value will be returned) + 2. Already existing 'Secret' resource + (If a 'Secret' resource is found under the name provided to the 'secret' parameter to this function and that 'Secret' resource contains a key with the name passed as the 'key' parameter to this function then the value of this existing secret password will be returned) + 3. Password provided via the values.yaml if honorProvidedValues = false + (If one of the keys passed to the 'providedValues' parameter to this function is a valid path to a key in the values.yaml and has a value, the value of the first key with a value will be returned) + 4. Randomly generated secret password + (A new random secret password with the length specified in the 'length' parameter will be generated and returned) + +*/}} +{{- define "common.secrets.passwords.manage" -}} + +{{- $password := "" }} +{{- $subchart := "" }} +{{- $chartName := default "" .chartName }} +{{- $passwordLength := default 10 .length }} +{{- $providedPasswordKey := include "common.utils.getKeyFromList" (dict "keys" .providedValues "context" $.context) }} +{{- $providedPasswordValue := include "common.utils.getValueFromKey" (dict "key" $providedPasswordKey "context" $.context) }} +{{- $secretData := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret).data }} +{{- if $secretData }} + {{- if hasKey $secretData .key }} + {{- $password = index $secretData .key | b64dec }} + {{- else if not (eq .failOnNew false) }} + {{- printf "\nPASSWORDS ERROR: The secret \"%s\" does not contain the key \"%s\"\n" .secret .key | fail -}} + {{- end -}} +{{- end }} + +{{- if and $providedPasswordValue .honorProvidedValues }} + {{- $password = tpl ($providedPasswordValue | toString) .context }} +{{- end }} + +{{- if not $password }} + {{- if $providedPasswordValue }} + {{- $password = tpl ($providedPasswordValue | toString) .context }} + {{- else }} + {{- if .context.Values.enabled }} + {{- $subchart = $chartName }} + {{- end -}} + + {{- if not (eq .failOnNew false) }} + {{- $requiredPassword := dict "valueKey" $providedPasswordKey "secret" .secret "field" .key "subchart" $subchart "context" $.context -}} + {{- $requiredPasswordError := include "common.validations.values.single.empty" $requiredPassword -}} + {{- $passwordValidationErrors := list $requiredPasswordError -}} + {{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $.context) -}} + {{- end }} + + {{- if .strong }} + {{- $subStr := list (lower (randAlpha 1)) (randNumeric 1) (upper (randAlpha 1)) | join "_" }} + {{- $password = randAscii $passwordLength }} + {{- $password = regexReplaceAllLiteral "\\W" $password "@" | substr 5 $passwordLength }} + {{- $password = printf "%s%s" $subStr $password | toString | shuffle }} + {{- else }} + {{- $password = randAlphaNum $passwordLength }} + {{- end }} + {{- end -}} +{{- end -}} +{{- if not .skipB64enc }} +{{- $password = $password | b64enc }} +{{- end -}} +{{- if .skipQuote -}} +{{- printf "%s" $password -}} +{{- else -}} +{{- printf "%s" $password | quote -}} +{{- end -}} +{{- end -}} + +{{/* +Reuses the value from an existing secret, otherwise sets its value to a default value. + +Usage: +{{ include "common.secrets.lookup" (dict "secret" "secret-name" "key" "keyName" "defaultValue" .Values.myValue "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - defaultValue - String - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - context - Context - Required - Parent context. + +*/}} +{{- define "common.secrets.lookup" -}} +{{- $value := "" -}} +{{- $secretData := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret).data -}} +{{- if and $secretData (hasKey $secretData .key) -}} + {{- $value = index $secretData .key -}} +{{- else if .defaultValue -}} + {{- $value = .defaultValue | toString | b64enc -}} +{{- end -}} +{{- if $value -}} +{{- printf "%s" $value -}} +{{- end -}} +{{- end -}} + +{{/* +Returns whether a previous generated secret already exists + +Usage: +{{ include "common.secrets.exists" (dict "secret" "secret-name" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - context - Context - Required - Parent context. +*/}} +{{- define "common.secrets.exists" -}} +{{- $secret := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret) }} +{{- if $secret }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_storage.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_storage.tpl new file mode 100644 index 0000000..aa75856 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_storage.tpl @@ -0,0 +1,21 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return the proper Storage Class +{{ include "common.storage.class" ( dict "persistence" .Values.path.to.the.persistence "global" $) }} +*/}} +{{- define "common.storage.class" -}} +{{- $storageClass := (.global).storageClass | default .persistence.storageClass | default (.global).defaultStorageClass | default "" -}} +{{- if $storageClass -}} + {{- if (eq "-" $storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else -}} + {{- printf "storageClassName: %s" $storageClass -}} + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_tplvalues.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_tplvalues.tpl new file mode 100644 index 0000000..a04f4c1 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_tplvalues.tpl @@ -0,0 +1,52 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Renders a value that contains template perhaps with scope if the scope is present. +Usage: +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $ ) }} +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $ "scope" $app ) }} +*/}} +{{- define "common.tplvalues.render" -}} +{{- $value := typeIs "string" .value | ternary .value (.value | toYaml) }} +{{- if contains "{{" (toJson .value) }} + {{- if .scope }} + {{- tpl (cat "{{- with $.RelativeScope -}}" $value "{{- end }}") (merge (dict "RelativeScope" .scope) .context) }} + {{- else }} + {{- tpl $value .context }} + {{- end }} +{{- else }} + {{- $value }} +{{- end }} +{{- end -}} + +{{/* +Merge a list of values that contains template after rendering them. +Merge precedence is consistent with http://masterminds.github.io/sprig/dicts.html#merge-mustmerge +Usage: +{{ include "common.tplvalues.merge" ( dict "values" (list .Values.path.to.the.Value1 .Values.path.to.the.Value2) "context" $ ) }} +*/}} +{{- define "common.tplvalues.merge" -}} +{{- $dst := dict -}} +{{- range .values -}} +{{- $dst = include "common.tplvalues.render" (dict "value" . "context" $.context "scope" $.scope) | fromYaml | merge $dst -}} +{{- end -}} +{{ $dst | toYaml }} +{{- end -}} + +{{/* +Merge a list of values that contains template after rendering them. +Merge precedence is consistent with https://masterminds.github.io/sprig/dicts.html#mergeoverwrite-mustmergeoverwrite +Usage: +{{ include "common.tplvalues.merge-overwrite" ( dict "values" (list .Values.path.to.the.Value1 .Values.path.to.the.Value2) "context" $ ) }} +*/}} +{{- define "common.tplvalues.merge-overwrite" -}} +{{- $dst := dict -}} +{{- range .values -}} +{{- $dst = include "common.tplvalues.render" (dict "value" . "context" $.context "scope" $.scope) | fromYaml | mergeOverwrite $dst -}} +{{- end -}} +{{ $dst | toYaml }} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_utils.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_utils.tpl new file mode 100644 index 0000000..d53c74a --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_utils.tpl @@ -0,0 +1,77 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Print instructions to get a secret value. +Usage: +{{ include "common.utils.secret.getvalue" (dict "secret" "secret-name" "field" "secret-value-field" "context" $) }} +*/}} +{{- define "common.utils.secret.getvalue" -}} +{{- $varname := include "common.utils.fieldToEnvVar" . -}} +export {{ $varname }}=$(kubectl get secret --namespace {{ include "common.names.namespace" .context | quote }} {{ .secret }} -o jsonpath="{.data.{{ .field }}}" | base64 -d) +{{- end -}} + +{{/* +Build env var name given a field +Usage: +{{ include "common.utils.fieldToEnvVar" dict "field" "my-password" }} +*/}} +{{- define "common.utils.fieldToEnvVar" -}} + {{- $fieldNameSplit := splitList "-" .field -}} + {{- $upperCaseFieldNameSplit := list -}} + + {{- range $fieldNameSplit -}} + {{- $upperCaseFieldNameSplit = append $upperCaseFieldNameSplit ( upper . ) -}} + {{- end -}} + + {{ join "_" $upperCaseFieldNameSplit }} +{{- end -}} + +{{/* +Gets a value from .Values given +Usage: +{{ include "common.utils.getValueFromKey" (dict "key" "path.to.key" "context" $) }} +*/}} +{{- define "common.utils.getValueFromKey" -}} +{{- $splitKey := splitList "." .key -}} +{{- $value := "" -}} +{{- $latestObj := $.context.Values -}} +{{- range $splitKey -}} + {{- if not $latestObj -}} + {{- printf "please review the entire path of '%s' exists in values" $.key | fail -}} + {{- end -}} + {{- $value = ( index $latestObj . ) -}} + {{- $latestObj = $value -}} +{{- end -}} +{{- printf "%v" (default "" $value) -}} +{{- end -}} + +{{/* +Returns first .Values key with a defined value or first of the list if all non-defined +Usage: +{{ include "common.utils.getKeyFromList" (dict "keys" (list "path.to.key1" "path.to.key2") "context" $) }} +*/}} +{{- define "common.utils.getKeyFromList" -}} +{{- $key := first .keys -}} +{{- $reverseKeys := reverse .keys }} +{{- range $reverseKeys }} + {{- $value := include "common.utils.getValueFromKey" (dict "key" . "context" $.context ) }} + {{- if $value -}} + {{- $key = . }} + {{- end -}} +{{- end -}} +{{- printf "%s" $key -}} +{{- end -}} + +{{/* +Checksum a template at "path" containing a *single* resource (ConfigMap,Secret) for use in pod annotations, excluding the metadata (see #18376). +Usage: +{{ include "common.utils.checksumTemplate" (dict "path" "/configmap.yaml" "context" $) }} +*/}} +{{- define "common.utils.checksumTemplate" -}} +{{- $obj := include (print .context.Template.BasePath .path) .context | fromYaml -}} +{{ omit $obj "apiVersion" "kind" "metadata" | toYaml | sha256sum }} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/_warnings.tpl b/charts/mayastor/charts/etcd/charts/common/templates/_warnings.tpl new file mode 100644 index 0000000..62c44df --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/_warnings.tpl @@ -0,0 +1,109 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Warning about using rolling tag. +Usage: +{{ include "common.warnings.rollingTag" .Values.path.to.the.imageRoot }} +*/}} +{{- define "common.warnings.rollingTag" -}} + +{{- if and (contains "bitnami/" .repository) (not (.tag | toString | regexFind "-r\\d+$|sha256:")) }} +WARNING: Rolling tag detected ({{ .repository }}:{{ .tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. ++info https://techdocs.broadcom.com/us/en/vmware-tanzu/application-catalog/tanzu-application-catalog/services/tac-doc/apps-tutorials-understand-rolling-tags-containers-index.html +{{- end }} +{{- end -}} + +{{/* +Warning about replaced images from the original. +Usage: +{{ include "common.warnings.modifiedImages" (dict "images" (list .Values.path.to.the.imageRoot) "context" $) }} +*/}} +{{- define "common.warnings.modifiedImages" -}} +{{- $affectedImages := list -}} +{{- $printMessage := false -}} +{{- $originalImages := .context.Chart.Annotations.images -}} +{{- range .images -}} + {{- $fullImageName := printf (printf "%s/%s:%s" .registry .repository .tag) -}} + {{- if not (contains $fullImageName $originalImages) }} + {{- $affectedImages = append $affectedImages (printf "%s/%s:%s" .registry .repository .tag) -}} + {{- $printMessage = true -}} + {{- end -}} +{{- end -}} +{{- if $printMessage }} + +⚠ SECURITY WARNING: Original containers have been substituted. This Helm chart was designed, tested, and validated on multiple platforms using a specific set of Bitnami and Tanzu Application Catalog containers. Substituting other containers is likely to cause degraded security and performance, broken chart features, and missing environment variables. + +Substituted images detected: +{{- range $affectedImages }} + - {{ . }} +{{- end }} +{{- end -}} +{{- end -}} + +{{/* +Warning about not setting the resource object in all deployments. +Usage: +{{ include "common.warnings.resources" (dict "sections" (list "path1" "path2") context $) }} +Example: +{{- include "common.warnings.resources" (dict "sections" (list "csiProvider.provider" "server" "volumePermissions" "") "context" $) }} +The list in the example assumes that the following values exist: + - csiProvider.provider.resources + - server.resources + - volumePermissions.resources + - resources +*/}} +{{- define "common.warnings.resources" -}} +{{- $values := .context.Values -}} +{{- $printMessage := false -}} +{{ $affectedSections := list -}} +{{- range .sections -}} + {{- if eq . "" -}} + {{/* Case where the resources section is at the root (one main deployment in the chart) */}} + {{- if not (index $values "resources") -}} + {{- $affectedSections = append $affectedSections "resources" -}} + {{- $printMessage = true -}} + {{- end -}} + {{- else -}} + {{/* Case where the are multiple resources sections (more than one main deployment in the chart) */}} + {{- $keys := split "." . -}} + {{/* We iterate through the different levels until arriving to the resource section. Example: a.b.c.resources */}} + {{- $section := $values -}} + {{- range $keys -}} + {{- $section = index $section . -}} + {{- end -}} + {{- if not (index $section "resources") -}} + {{/* If the section has enabled=false or replicaCount=0, do not include it */}} + {{- if and (hasKey $section "enabled") -}} + {{- if index $section "enabled" -}} + {{/* enabled=true */}} + {{- $affectedSections = append $affectedSections (printf "%s.resources" .) -}} + {{- $printMessage = true -}} + {{- end -}} + {{- else if and (hasKey $section "replicaCount") -}} + {{/* We need a casting to int because number 0 is not treated as an int by default */}} + {{- if (gt (index $section "replicaCount" | int) 0) -}} + {{/* replicaCount > 0 */}} + {{- $affectedSections = append $affectedSections (printf "%s.resources" .) -}} + {{- $printMessage = true -}} + {{- end -}} + {{- else -}} + {{/* Default case, add it to the affected sections */}} + {{- $affectedSections = append $affectedSections (printf "%s.resources" .) -}} + {{- $printMessage = true -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- if $printMessage }} + +WARNING: There are "resources" sections in the chart not set. Using "resourcesPreset" is not recommended for production. For production installations, please set the following values according to your workload needs: +{{- range $affectedSections }} + - {{ . }} +{{- end }} ++info https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/validations/_cassandra.tpl b/charts/mayastor/charts/etcd/charts/common/templates/validations/_cassandra.tpl new file mode 100644 index 0000000..f8fd213 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/validations/_cassandra.tpl @@ -0,0 +1,51 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.cassandra.values.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.cassandra.dbUser.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.dbUser.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled cassandra. + +Usage: +{{ include "common.cassandra.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.cassandra.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.cassandra.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key dbUser + +Usage: +{{ include "common.cassandra.values.key.dbUser" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.key.dbUser" -}} + {{- if .subchart -}} + cassandra.dbUser + {{- else -}} + dbUser + {{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/validations/_mariadb.tpl b/charts/mayastor/charts/etcd/charts/common/templates/validations/_mariadb.tpl new file mode 100644 index 0000000..6ea8c0f --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/validations/_mariadb.tpl @@ -0,0 +1,108 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MariaDB required passwords are not empty. + +Usage: +{{ include "common.validations.values.mariadb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MariaDB values are stored, e.g: "mysql-passwords-secret" + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mariadb.passwords" -}} + {{- $existingSecret := include "common.mariadb.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mariadb.values.enabled" . -}} + {{- $architecture := include "common.mariadb.values.architecture" . -}} + {{- $authPrefix := include "common.mariadb.values.key.auth" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicationPassword := printf "%s.replicationPassword" $authPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mariadb-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- if not (empty $valueUsername) -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mariadb-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replication") -}} + {{- $requiredReplicationPassword := dict "valueKey" $valueKeyReplicationPassword "secret" .secret "field" "mariadb-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mariadb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mariadb. + +Usage: +{{ include "common.mariadb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mariadb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mariadb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mariadb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mariadb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.key.auth" -}} + {{- if .subchart -}} + mariadb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/validations/_mongodb.tpl b/charts/mayastor/charts/etcd/charts/common/templates/validations/_mongodb.tpl new file mode 100644 index 0000000..e678a6d --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/validations/_mongodb.tpl @@ -0,0 +1,67 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mongodb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDb is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mongodb. + +Usage: +{{ include "common.mongodb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mongodb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mongodb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mongodb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.key.auth" -}} + {{- if .subchart -}} + mongodb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mongodb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/validations/_mysql.tpl b/charts/mayastor/charts/etcd/charts/common/templates/validations/_mysql.tpl new file mode 100644 index 0000000..fbb65c3 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/validations/_mysql.tpl @@ -0,0 +1,67 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mysql.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mysql.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mysql. + +Usage: +{{ include "common.mysql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mysql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mysql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mysql.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mysql.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mysql.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.key.auth" -}} + {{- if .subchart -}} + mysql.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/validations/_postgresql.tpl b/charts/mayastor/charts/etcd/charts/common/templates/validations/_postgresql.tpl new file mode 100644 index 0000000..51d4716 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/validations/_postgresql.tpl @@ -0,0 +1,105 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Auxiliary function to decide whether evaluate global values. + +Usage: +{{ include "common.postgresql.values.use.global" (dict "key" "key-of-global" "context" $) }} +Params: + - key - String - Required. Field to be evaluated within global, e.g: "existingSecret" +*/}} +{{- define "common.postgresql.values.use.global" -}} + {{- if .context.Values.global -}} + {{- if .context.Values.global.postgresql -}} + {{- index .context.Values.global.postgresql .key | quote -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.postgresql.values.existingSecret" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.existingSecret" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "existingSecret" "context" .context) -}} + + {{- if .subchart -}} + {{- default (.context.Values.postgresql.existingSecret | quote) $globalValue -}} + {{- else -}} + {{- default (.context.Values.existingSecret | quote) $globalValue -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled postgresql. + +Usage: +{{ include "common.postgresql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key postgressPassword. + +Usage: +{{ include "common.postgresql.values.key.postgressPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.postgressPassword" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "postgresqlUsername" "context" .context) -}} + + {{- if not $globalValue -}} + {{- if .subchart -}} + postgresql.postgresqlPassword + {{- else -}} + postgresqlPassword + {{- end -}} + {{- else -}} + global.postgresql.postgresqlPassword + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled.replication. + +Usage: +{{ include "common.postgresql.values.enabled.replication" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.enabled.replication" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.replication.enabled -}} + {{- else -}} + {{- printf "%v" .context.Values.replication.enabled -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key replication.password. + +Usage: +{{ include "common.postgresql.values.key.replicationPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.replicationPassword" -}} + {{- if .subchart -}} + postgresql.replication.password + {{- else -}} + replication.password + {{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/validations/_redis.tpl b/charts/mayastor/charts/etcd/charts/common/templates/validations/_redis.tpl new file mode 100644 index 0000000..9fedfef --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/validations/_redis.tpl @@ -0,0 +1,48 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + + +{{/* vim: set filetype=mustache: */}} +{{/* +Auxiliary function to get the right value for enabled redis. + +Usage: +{{ include "common.redis.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.redis.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.redis.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right prefix path for the values + +Usage: +{{ include "common.redis.values.key.prefix" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false +*/}} +{{- define "common.redis.values.keys.prefix" -}} + {{- if .subchart -}}redis.{{- else -}}{{- end -}} +{{- end -}} + +{{/* +Checks whether the redis chart's includes the standarizations (version >= 14) + +Usage: +{{ include "common.redis.values.standarized.version" (dict "context" $) }} +*/}} +{{- define "common.redis.values.standarized.version" -}} + + {{- $standarizedAuth := printf "%s%s" (include "common.redis.values.keys.prefix" .) "auth" -}} + {{- $standarizedAuthValues := include "common.utils.getValueFromKey" (dict "key" $standarizedAuth "context" .context) }} + + {{- if $standarizedAuthValues -}} + {{- true -}} + {{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/templates/validations/_validations.tpl b/charts/mayastor/charts/etcd/charts/common/templates/validations/_validations.tpl new file mode 100644 index 0000000..7cdee61 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/templates/validations/_validations.tpl @@ -0,0 +1,51 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate values must not be empty. + +Usage: +{{- $validateValueConf00 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-01") -}} +{{ include "common.validations.values.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" +*/}} +{{- define "common.validations.values.multiple.empty" -}} + {{- range .required -}} + {{- include "common.validations.values.single.empty" (dict "valueKey" .valueKey "secret" .secret "field" .field "context" $.context) -}} + {{- end -}} +{{- end -}} + +{{/* +Validate a value must not be empty. + +Usage: +{{ include "common.validations.value.empty" (dict "valueKey" "mariadb.password" "secret" "secretName" "field" "my-password" "subchart" "subchart" "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" + - subchart - String - Optional - Name of the subchart that the validated password is part of. +*/}} +{{- define "common.validations.values.single.empty" -}} + {{- $value := include "common.utils.getValueFromKey" (dict "key" .valueKey "context" .context) }} + {{- $subchart := ternary "" (printf "%s." .subchart) (empty .subchart) }} + + {{- if not $value -}} + {{- $varname := "my-value" -}} + {{- $getCurrentValue := "" -}} + {{- if and .secret .field -}} + {{- $varname = include "common.utils.fieldToEnvVar" . -}} + {{- $getCurrentValue = printf " To get the current value:\n\n %s\n" (include "common.utils.secret.getvalue" .) -}} + {{- end -}} + {{- printf "\n '%s' must not be empty, please add '--set %s%s=$%s' to the command.%s" .valueKey $subchart .valueKey $varname $getCurrentValue -}} + {{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/charts/common/values.yaml b/charts/mayastor/charts/etcd/charts/common/values.yaml new file mode 100644 index 0000000..de2cac5 --- /dev/null +++ b/charts/mayastor/charts/etcd/charts/common/values.yaml @@ -0,0 +1,8 @@ +# Copyright Broadcom, Inc. All Rights Reserved. +# SPDX-License-Identifier: APACHE-2.0 + +## bitnami/common +## It is required by CI/CD tools and processes. +## @skip exampleValue +## +exampleValue: common-chart diff --git a/charts/mayastor/charts/etcd/templates/NOTES.txt b/charts/mayastor/charts/etcd/templates/NOTES.txt new file mode 100644 index 0000000..864c990 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/NOTES.txt @@ -0,0 +1,122 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +NOTICE: Starting August 28th, 2025, only a limited subset of images/charts will remain available for free. Backup will be available for some time at the 'Bitnami Legacy' repository. More info at https://github.com/bitnami/containers/issues/83267 + +{{- if and (eq .Values.service.type "LoadBalancer") .Values.auth.rbac.allowNoneAuthentication }} +------------------------------------------------------------------------------- + WARNING + + By specifying "service.type=LoadBalancer", "auth.rbac.enabled=false" and + "auth.rbac.allowNoneAuthentication=true" you have most likely exposed the etcd + service externally without any authentication mechanism. + + For security reasons, we strongly suggest that you switch to "ClusterIP" or + "NodePort". As alternative, you can also switch to "auth.rbac.enabled=true" + providing a valid password on "auth.rbac.rootPassword" parameter. + +------------------------------------------------------------------------------- +{{- end }} + +** Please be patient while the chart is being deployed ** + +{{- if .Values.diagnosticMode.enabled }} +The chart has been deployed in diagnostic mode. All probes have been disabled and the command has been overwritten with: + + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 4 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 4 }} + +Get the list of pods by executing: + + kubectl get pods --namespace {{ include "common.names.namespace" . }} -l app.kubernetes.io/instance={{ .Release.Name }} + +Access the pod you want to debug by executing + + kubectl exec --namespace {{ include "common.names.namespace" . }} -ti -- bash + +In order to replicate the container startup scripts execute this command: + + /opt/bitnami/scripts/etcd/entrypoint.sh /opt/bitnami/scripts/etcd/run.sh + +{{- else }} + +etcd can be accessed via port {{ .Values.service.ports.client }} on the following DNS name from within your cluster: + + {{ template "common.names.fullname" . }}.{{ include "common.names.namespace" . }}.svc.{{ .Values.clusterDomain }} + +To create a pod that you can use as a etcd client run the following command: + + kubectl run {{ template "common.names.fullname" . }}-client --restart='Never' --image {{ template "etcd.image" . }}{{- if or .Values.auth.rbac.create .Values.auth.rbac.enabled }} --env ROOT_PASSWORD=$(kubectl get secret --namespace {{ include "common.names.namespace" . }} {{ if .Values.auth.rbac.existingSecret }}{{ .Values.auth.rbac.existingSecret }}{{ else }}{{ template "common.names.fullname" . }}{{ end }} -o jsonpath="{{ if .Values.auth.rbac.existingSecret }}{.data.{{ .Values.auth.rbac.existingSecretPasswordKey }}}{{ else }}{.data.etcd-root-password}{{ end }}" | base64 -d){{- end }} --env ETCDCTL_ENDPOINTS="{{ template "common.names.fullname" . }}.{{ include "common.names.namespace" . }}.svc.{{ .Values.clusterDomain }}:{{ .Values.service.ports.client }}" --namespace {{ include "common.names.namespace" . }} --command -- sleep infinity + +Then, you can set/get a key using the commands below: + + kubectl exec --namespace {{ include "common.names.namespace" . }} -it {{ template "common.names.fullname" . }}-client -- bash + {{- $etcdAuthOptions := include "etcd.authOptions" . }} + etcdctl {{ $etcdAuthOptions }} put /message Hello + etcdctl {{ $etcdAuthOptions }} get /message + +To connect to your etcd server from outside the cluster execute the following commands: + +{{- if contains "NodePort" .Values.service.type }} + + export NODE_IP=$(kubectl get nodes --namespace {{ include "common.names.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}") + export NODE_PORT=$(kubectl get --namespace {{ include "common.names.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "common.names.fullname" . }}) + echo "etcd URL: http://$NODE_IP:$NODE_PORT/" + +{{- else if contains "LoadBalancer" .Values.service.type }} + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace {{ include "common.names.namespace" . }} -w {{ template "common.names.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ include "common.names.namespace" . }} {{ template "common.names.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") + echo "etcd URL: http://$SERVICE_IP:{{ .Values.service.ports.client }}/" + +{{- else if contains "ClusterIP" .Values.service.type }} + + kubectl port-forward --namespace {{ include "common.names.namespace" . }} svc/{{ template "common.names.fullname" . }} {{ .Values.service.ports.client }}:{{ .Values.service.ports.client }} & + echo "etcd URL: http://127.0.0.1:{{ .Values.service.ports.client }}" + +{{- end }} +{{- if or .Values.auth.rbac.create .Values.auth.rbac.enabled }} + + * As rbac is enabled you should add the flag `--user root:$ETCD_ROOT_PASSWORD` to the etcdctl commands. Use the command below to export the password: + + export ETCD_ROOT_PASSWORD=$(kubectl get secret --namespace {{ include "common.names.namespace" . }} {{ if .Values.auth.rbac.existingSecret }}{{ .Values.auth.rbac.existingSecret }}{{ else }}{{ template "common.names.fullname" . }}{{ end }} -o jsonpath="{{ if .Values.auth.rbac.existingSecret }}{.data.{{ .Values.auth.rbac.existingSecretPasswordKey }}}{{ else }}{.data.etcd-root-password}{{ end }}" | base64 -d) + +{{- end }} +{{- if .Values.auth.client.secureTransport }} +{{- if .Values.auth.client.useAutoTLS }} + + * As TLS is enabled you should add the flag `--cert-file /bitnami/etcd/data/fixtures/client/cert.pem --key-file /bitnami/etcd/data/fixtures/client/key.pem --insecure-skip-tls-verify` to the etcdctl commands. + +{{- else }} + + * As TLS is enabled you should add the flag `--cert-file /opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certFilename }} --key-file /opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certKeyFilename }}` to the etcdctl commands. + +{{- end }} + + * You should also export a proper etcdctl endpoint using the https schema. Eg. + + export ETCDCTL_ENDPOINTS=https://{{ template "common.names.fullname" . }}-0:{{ .Values.service.ports.client }} + +{{- end }} +{{- if .Values.auth.client.enableAuthentication }} + + * As TLS host authentication is enabled you should add the flag `--ca-file /opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename | default "ca.crt" }}` to the etcdctl commands. + +{{- end }} +{{- $autoCompactionValue := (regexReplaceAll "[^0-9]" .Values.autoCompactionRetention "" | int) }} +{{- if and .Values.defrag.enabled (or (empty .Values.autoCompactionRetention) (eq $autoCompactionValue 0)) }} + + * Disk defragmentation in etcd is most effective when paired with key history auto compaction. Consider setting "autoCompactionRetention > 0". + +{{- end }} +{{- end }} + +{{- include "common.warnings.rollingTag" .Values.image }} +{{- include "common.warnings.rollingTag" .Values.volumePermissions.image }} +{{- include "etcd.validateValues" . }} +{{- include "common.warnings.resources" (dict "sections" (list "" "volumePermissions" "preUpgradeJob" "disasterRecovery.cronjob") "context" $) }} +{{- include "common.warnings.modifiedImages" (dict "images" (list .Values.image .Values.volumePermissions.image) "context" $) }} +{{- include "common.errors.insecureImages" (dict "images" (list .Values.image .Values.volumePermissions.image) "context" $) }} diff --git a/charts/mayastor/charts/etcd/templates/_helpers.tpl b/charts/mayastor/charts/etcd/templates/_helpers.tpl new file mode 100644 index 0000000..68733c2 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/_helpers.tpl @@ -0,0 +1,213 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return the proper etcd image name +*/}} +{{- define "etcd.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper image name (for the init container volume-permissions image) +*/}} +{{- define "etcd.volumePermissions.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.volumePermissions.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "etcd.imagePullSecrets" -}} +{{ include "common.images.pullSecrets" (dict "images" (list .Values.image .Values.volumePermissions.image) "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper etcd peer protocol +*/}} +{{- define "etcd.peerProtocol" -}} +{{- if .Values.auth.peer.secureTransport -}} +{{- print "https" -}} +{{- else -}} +{{- print "http" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper etcd client protocol +*/}} +{{- define "etcd.clientProtocol" -}} +{{- if .Values.auth.client.secureTransport -}} +{{- print "https" -}} +{{- else -}} +{{- print "http" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper etcdctl authentication options +*/}} +{{- define "etcd.authOptions" -}} +{{- $rbacOption := "--user root:$ROOT_PASSWORD" -}} +{{- $certsOption := " --cert $ETCD_CERT_FILE --key $ETCD_KEY_FILE" -}} +{{- $autoCertsOption := " --cert /bitnami/etcd/data/fixtures/client/cert.pem --key /bitnami/etcd/data/fixtures/client/key.pem --insecure-skip-tls-verify" -}} +{{- $caOption := " --cacert $ETCD_TRUSTED_CA_FILE" -}} +{{- $insecureTlsOption := " --insecure-skip-tls-verify" -}} +{{- if or .Values.auth.rbac.create .Values.auth.rbac.enabled -}} + {{- printf "%s" $rbacOption -}} +{{- end -}} +{{- if and .Values.auth.client.secureTransport .Values.auth.client.useAutoTLS -}} + {{- printf "%s" $autoCertsOption -}} +{{- else if and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS) -}} + {{- printf "%s" $certsOption -}} + {{- if or .Values.auth.client.enableAuthentication .Values.auth.client.caFilename -}} + {{- printf "%s" $caOption -}} + {{- else -}} + {{- printf "%s" $insecureTlsOption -}} + {{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Return the etcd configuration configmap +*/}} +{{- define "etcd.configmapName" -}} +{{- if .Values.existingConfigmap -}} + {{- printf "%s" (tpl .Values.existingConfigmap $) | trunc 63 | trimSuffix "-" -}} +{{- else -}} + {{- printf "%s-configuration" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a configmap object should be created +*/}} +{{- define "etcd.createConfigmap" -}} +{{- if and .Values.configuration (not .Values.existingConfigmap) }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return the secret with etcd credentials +*/}} +{{- define "etcd.secretName" -}} + {{- if .Values.auth.rbac.existingSecret -}} + {{- printf "%s" .Values.auth.rbac.existingSecret | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s" (include "common.names.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{/* +Get the secret password key to be retrieved from etcd secret. +*/}} +{{- define "etcd.secretPasswordKey" -}} +{{- if and .Values.auth.rbac.existingSecret .Values.auth.rbac.existingSecretPasswordKey -}} +{{- printf "%s" .Values.auth.rbac.existingSecretPasswordKey -}} +{{- else -}} +{{- printf "etcd-root-password" -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a secret object should be created for the etcd token private key +*/}} +{{- define "etcd.token.createSecret" -}} +{{- if and (eq .Values.auth.token.enabled true) (eq .Values.auth.token.type "jwt") (empty .Values.auth.token.privateKey.existingSecret) }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return the secret with etcd token private key +*/}} +{{- define "etcd.token.secretName" -}} + {{- if .Values.auth.token.privateKey.existingSecret -}} + {{- printf "%s" .Values.auth.token.privateKey.existingSecret | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s-jwt-token" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the proper Disaster Recovery PVC name +*/}} +{{- define "etcd.disasterRecovery.pvc.name" -}} +{{- if .Values.disasterRecovery.pvc.existingClaim -}} + {{- printf "%s" (tpl .Values.disasterRecovery.pvc.existingClaim $) | trunc 63 | trimSuffix "-" -}} +{{- else if .Values.startFromSnapshot.existingClaim -}} + {{- printf "%s" (tpl .Values.startFromSnapshot.existingClaim $) | trunc 63 | trimSuffix "-" -}} +{{- else -}} + {{- printf "%s-snapshotter" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} +{{- end -}} +{{- end -}} + +{{/* + Create the name of the service account to use + */}} +{{- define "etcd.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} +{{ default (include "common.names.fullname" .) .Values.serviceAccount.name | trunc 63 | trimSuffix "-" }} +{{- else -}} +{{ default "default" .Values.serviceAccount.name | trunc 63 | trimSuffix "-" }} +{{- end -}} +{{- end -}} + +{{/* +Compile all warnings into a single message, and call fail. +*/}} +{{- define "etcd.validateValues" -}} +{{- $messages := list -}} +{{- $messages := append $messages (include "etcd.validateValues.startFromSnapshot.existingClaim" .) -}} +{{- $messages := append $messages (include "etcd.validateValues.startFromSnapshot.snapshotFilename" .) -}} +{{- $messages := append $messages (include "etcd.validateValues.disasterRecovery" .) -}} +{{- $messages := without $messages "" -}} +{{- $message := join "\n" $messages -}} + +{{- if $message -}} +{{- printf "\nVALUES VALIDATION:\n%s" $message | fail -}} +{{- end -}} +{{- end -}} + +{{/* Validate values of etcd - an existing claim must be provided when startFromSnapshot is enabled */}} +{{- define "etcd.validateValues.startFromSnapshot.existingClaim" -}} +{{- if and .Values.startFromSnapshot.enabled (not .Values.startFromSnapshot.existingClaim) (not .Values.disasterRecovery.enabled) -}} +etcd: startFromSnapshot.existingClaim + An existing claim must be provided when startFromSnapshot is enabled and disasterRecovery is disabled!! + Please provide it (--set startFromSnapshot.existingClaim="xxxx") +{{- end -}} +{{- end -}} + +{{/* Validate values of etcd - the snapshot filename must be provided when startFromSnapshot is enabled */}} +{{- define "etcd.validateValues.startFromSnapshot.snapshotFilename" -}} +{{- if and .Values.startFromSnapshot.enabled (not .Values.startFromSnapshot.snapshotFilename) (not .Values.disasterRecovery.enabled) -}} +etcd: startFromSnapshot.snapshotFilename + The snapshot filename must be provided when startFromSnapshot is enabled and disasterRecovery is disabled!! + Please provide it (--set startFromSnapshot.snapshotFilename="xxxx") +{{- end -}} +{{- end -}} + +{{/* Validate values of etcd - persistence must be enabled when disasterRecovery is enabled */}} +{{- define "etcd.validateValues.disasterRecovery" -}} +{{- if and .Values.disasterRecovery.enabled (not .Values.persistence.enabled) -}} +etcd: disasterRecovery + Persistence must be enabled when disasterRecovery is enabled!! + Please enable persistence (--set persistence.enabled=true) +{{- end -}} +{{- end -}} + +{{- define "etcd.token.jwtToken" -}} +{{- if (include "etcd.token.createSecret" .) -}} +{{- $jwtToken := lookup "v1" "Secret" (include "common.names.namespace" .) (printf "%s-jwt-token" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" ) -}} +{{- if $jwtToken -}} +{{ index $jwtToken "data" "jwt-token.pem" | b64dec }} +{{- else -}} +{{ genPrivateKey "rsa" }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/templates/configmap.yaml b/charts/mayastor/charts/etcd/templates/configmap.yaml new file mode 100644 index 0000000..8588631 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/configmap.yaml @@ -0,0 +1,20 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if (include "etcd.createConfigmap" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ printf "%s-configuration" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: etcd + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + etcd.conf.yml: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.configuration "context" $ ) | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/etcd/templates/cronjob-defrag.yaml b/charts/mayastor/charts/etcd/templates/cronjob-defrag.yaml new file mode 100644 index 0000000..71b14cb --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/cronjob-defrag.yaml @@ -0,0 +1,169 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.defrag.enabled }} +apiVersion: {{ include "common.capabilities.cronjob.apiVersion" . }} +kind: CronJob +metadata: + name: {{ printf "%s-defrag" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.defrag.cronjob.labels .Values.commonLabels ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + {{- if or .Values.defrag.cronjob.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.defrag.cronjob.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.defrag.cronjob.startingDeadlineSeconds }} + startingDeadlineSeconds: {{ .Values.defrag.cronjob.startingDeadlineSeconds }} + {{- end }} + concurrencyPolicy: {{ .Values.defrag.cronjob.concurrencyPolicy }} + schedule: {{ .Values.defrag.cronjob.schedule | quote }} + suspend: {{ .Values.defrag.cronjob.suspend }} + successfulJobsHistoryLimit: {{ .Values.defrag.cronjob.successfulJobsHistoryLimit }} + failedJobsHistoryLimit: {{ .Values.defrag.cronjob.failedJobsHistoryLimit }} + jobTemplate: + spec: + template: + metadata: + {{- $mergedLabels := mergeOverwrite (dict) .Values.commonLabels .Values.defrag.cronjob.podLabels }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $mergedLabels "context" $ ) | nindent 12 }} + {{- if .Values.defrag.cronjob.podAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.defrag.cronjob.podAnnotations "context" $) | nindent 12 }} + {{- end }} + spec: + {{- if .Values.defrag.cronjob.activeDeadlineSeconds }} + activeDeadlineSeconds: {{ .Values.defrag.cronjob.activeDeadlineSeconds }} + {{- end }} + restartPolicy: {{ .Values.defrag.cronjob.restartPolicy }} + {{- if .Values.defrag.cronjob.podSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.defrag.cronjob.podSecurityContext "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.defrag.cronjob.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.defrag.cronjob.nodeSelector "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.defrag.cronjob.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.defrag.cronjob.tolerations "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.defrag.cronjob.serviceAccountName }} + serviceAccountName: {{ .Values.defrag.cronjob.serviceAccountName | quote }} + {{- end }} + containers: + - name: etcd-defrag + image: {{ include "etcd.image" . }} + imagePullPolicy: "IfNotPresent" + {{- if .Values.defrag.cronjob.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.defrag.cronjob.containerSecurityContext "context" $) | nindent 16 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + {{- if and .Values.auth.rbac.create .Values.auth.token.enabled }} + {{- if .Values.usePasswordFiles }} + - name: ETCD_ROOT_PASSWORD_FILE + value: {{ printf "/opt/bitnami/etcd/secrets/%s" (include "etcd.secretPasswordKey" .) }} + {{- else }} + - name: ETCD_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "etcd.secretName" . }} + key: {{ include "etcd.secretPasswordKey" . }} + {{- end }} + {{- end }} + {{- if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS )) }} + - name: ETCDCTL_CACERT + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename | default "ca.crt" }}" + - name: ETCDCTL_KEY + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certKeyFilename }}" + - name: ETCDCTL_CERT + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certFilename }}" + {{- end }} + {{- if .Values.defrag.cronjob.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + {{- if or .Values.defrag.cronjob.extraEnvVarsCM .Values.defrag.cronjob.extraEnvVarsSecret }} + envFrom: + {{- if .Values.defrag.cronjob.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.defrag.cronjob.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.defrag.cronjob.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.defrag.cronjob.extraEnvVarsSecret "context" $) }} + {{- end }} + {{- end }} + {{- if .Values.defrag.cronjob.command }} + command: {{ .Values.defrag.cronjob.command | toYaml | nindent 16 }} + {{- else }} + command: + - /bin/bash + - -c + - |- + #!/usr/bin/env bash + set -eo pipefail + + # Include library + . /opt/bitnami/scripts/libetcd.sh + + # Load etcd environment settings + . /opt/bitnami/scripts/etcd-env.sh + + # Common flags + read -r -a flags <<<"$(etcdctl_auth_flags)" + cmd="etcdctl --command-timeout=60s ${flags[@]}" + {{- $etcdFullname := include "common.names.fullname" . }} + {{- $etcdHeadlessServiceName := (printf "%s-%s" $etcdFullname "headless" | trunc 63 | trimSuffix "-") }} + {{- $namespace := include "common.names.namespace" . }} + {{- $clusterDomain := .Values.clusterDomain }} + {{- $port := int .Values.service.ports.client }} + {{- $endpointStr := "" }} + {{- $replicaCount := (int .Values.replicaCount) }} + {{- $releaseNamespace := include "common.names.namespace" . }} + {{- range $iEndpoint, $e := until $replicaCount }} + {{- $endpoint := printf "%s://%s-%d.%s.%s.svc.%s:%d" (include "etcd.clientProtocol" $) $etcdFullname $iEndpoint $etcdHeadlessServiceName $namespace $clusterDomain $port }} + {{- $endpointStr = printf "%s%s" $endpointStr $endpoint }} + {{- if ne $iEndpoint (sub $replicaCount 1) }} + {{- $endpointStr = printf "%s," $endpointStr }} + {{- end }} + {{- end }} + {{- $endpointStr = printf "%s" $endpointStr }} + $cmd --endpoints={{ $endpointStr | quote}} defrag + {{- end }} + {{- if .Values.defrag.cronjob.args }} + args: {{ .Values.defrag.cronjob.args | toYaml | nindent 16 }} + {{- end }} + {{- if .Values.defrag.cronjob.resources }} + resources: {{- toYaml .Values.defrag.cronjob.resources | nindent 16 }} + {{- else if ne .Values.defrag.cronjob.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.defrag.cronjob.resourcesPreset) | nindent 16 }} + {{- end }} + volumeMounts: + {{- if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS )) }} + - name: etcd-client-certs + mountPath: /opt/bitnami/etcd/certs/client/ + readOnly: true + {{- end }} + {{- if and .Values.usePasswordFiles (or .Values.auth.rbac.create .Values.auth.rbac.enabled) }} + - name: etcd-secrets + mountPath: /opt/bitnami/etcd/secrets/ + readOnly: true + {{- end }} + {{- if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS )) (and .Values.usePasswordFiles (or .Values.auth.rbac.create .Values.auth.rbac.enabled)) }} + volumes: + {{- if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS )) }} + - name: etcd-client-certs + secret: + secretName: {{ required "A secret containing the client certificates is required" (tpl .Values.auth.client.existingSecret .) }} + defaultMode: 256 + {{- end }} + {{- if and .Values.usePasswordFiles (or .Values.auth.rbac.create .Values.auth.rbac.enabled) }} + - name: etcd-secrets + projected: + sources: + - secret: + name: {{ include "etcd.secretName" . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/etcd/templates/cronjob-snapshotter.yaml b/charts/mayastor/charts/etcd/templates/cronjob-snapshotter.yaml new file mode 100644 index 0000000..60da731 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/cronjob-snapshotter.yaml @@ -0,0 +1,171 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.disasterRecovery.enabled -}} +{{- $mergedLabels := mergeOverwrite (dict) .Values.commonLabels .Values.disasterRecovery.cronjob.podLabels -}} +apiVersion: {{ include "common.capabilities.cronjob.apiVersion" . }} +kind: CronJob +metadata: + name: {{ printf "%s-snapshotter" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + concurrencyPolicy: Forbid + schedule: {{ .Values.disasterRecovery.cronjob.schedule | quote }} + successfulJobsHistoryLimit: {{ .Values.disasterRecovery.cronjob.historyLimit }} + jobTemplate: + spec: + template: + metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" $mergedLabels "context" $ ) | nindent 12 }} + app.kubernetes.io/component: snapshotter + {{- if .Values.disasterRecovery.cronjob.podAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.disasterRecovery.cronjob.podAnnotations "context" $) | nindent 12 }} + {{- end }} + spec: + {{- include "etcd.imagePullSecrets" . | nindent 10 }} + {{- if .Values.disasterRecovery.cronjob.nodeSelector }} + nodeSelector: {{- toYaml .Values.disasterRecovery.cronjob.nodeSelector | nindent 12 }} + {{- end }} + {{- if .Values.disasterRecovery.cronjob.tolerations }} + tolerations: {{- toYaml .Values.disasterRecovery.cronjob.tolerations | nindent 12 }} + {{- end }} + restartPolicy: OnFailure + {{- if .Values.disasterRecovery.cronjob.podSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.disasterRecovery.cronjob.podSecurityContext "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.disasterRecovery.cronjob.serviceAccountName }} + serviceAccountName: {{ .Values.disasterRecovery.cronjob.serviceAccountName | quote }} + {{- end }} + {{- if and .Values.volumePermissions.enabled (or .Values.podSecurityContext.enabled .Values.containerSecurityContext.enabled) }} + initContainers: + - name: volume-permissions + image: {{ include "etcd.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: + - /bin/bash + - -ec + - | + chown -R {{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.podSecurityContext.fsGroup }} /snapshots + securityContext: + runAsUser: 0 + {{- if .Values.volumePermissions.resources }} + resources: {{- include "common.tplvalues.render" (dict "value" .Values.volumePermissions.resources "context" $) | nindent 16 }} + {{- end }} + volumeMounts: + - name: snapshot-volume + mountPath: /snapshots + - name: empty-dir + mountPath: /tmp + {{- end }} + containers: + - name: etcd-snapshotter + image: {{ include "etcd.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.disasterRecovery.cronjob.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.disasterRecovery.cronjob.containerSecurityContext "context" $) | nindent 16 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 16 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 16 }} + {{- else if .Values.disasterRecovery.cronjob.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.disasterRecovery.cronjob.command "context" $) | nindent 16 }} + {{- else }} + command: + - /opt/bitnami/scripts/etcd/snapshot.sh + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + - name: ETCD_ON_K8S + value: "yes" + - name: MY_STS_NAME + value: {{ include "common.names.fullname" . | quote }} + {{- $releaseNamespace := include "common.names.namespace" . }} + {{- $etcdFullname := include "common.names.fullname" . }} + {{- $etcdHeadlessServiceName := (printf "%s-%s" $etcdFullname "headless" | trunc 63 | trimSuffix "-") }} + {{- $clusterDomain := .Values.clusterDomain }} + - name: ETCD_CLUSTER_DOMAIN + value: {{ printf "%s.%s.svc.%s" $etcdHeadlessServiceName $releaseNamespace $clusterDomain | quote }} + - name: ETCD_SNAPSHOT_HISTORY_LIMIT + value: {{ .Values.disasterRecovery.cronjob.snapshotHistoryLimit | quote }} + - name: ETCD_SNAPSHOTS_DIR + value: {{ .Values.disasterRecovery.cronjob.snapshotsDir | quote }} + {{- if .Values.auth.client.secureTransport }} + - name: ETCD_CERT_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certFilename }}" + - name: ETCD_KEY_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certKeyFilename }}" + {{- if .Values.auth.client.enableAuthentication }} + - name: ETCD_CLIENT_CERT_AUTH + value: "true" + - name: ETCD_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename | default "ca.crt" }}" + {{- else if .Values.auth.client.caFilename }} + - name: ETCD_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename }}" + {{- else }} + - name: ETCD_EXTRA_AUTH_FLAGS + value: "--insecure-skip-tls-verify" + {{- end }} + {{- end }} + {{- if or .Values.auth.rbac.create .Values.auth.rbac.enabled }} + {{- if .Values.usePasswordFiles }} + - name: ETCD_ROOT_PASSWORD_FILE + value: {{ printf "/opt/bitnami/etcd/secrets/%s" (include "etcd.secretPasswordKey" .) }} + {{- else }} + - name: ETCD_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "etcd.secretName" . }} + key: {{ include "etcd.secretPasswordKey" . }} + {{- end }} + {{- end }} + {{- if .Values.disasterRecovery.cronjob.resources }} + resources: {{- toYaml .Values.disasterRecovery.cronjob.resources | nindent 16 }} + {{- else if ne .Values.disasterRecovery.cronjob.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.disasterRecovery.cronjob.resourcesPreset) | nindent 16 }} + {{- end }} + volumeMounts: + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + - name: snapshot-volume + mountPath: /snapshots + {{- if .Values.disasterRecovery.pvc.subPath }} + subPath: {{ .Values.disasterRecovery.pvc.subPath }} + {{- end }} + {{- if .Values.auth.client.secureTransport }} + - name: certs + mountPath: /opt/bitnami/etcd/certs/client + readOnly: true + {{- end }} + {{- if and .Values.usePasswordFiles (or .Values.auth.rbac.create .Values.auth.rbac.enabled) }} + - name: etcd-secrets + mountPath: /opt/bitnami/etcd/secrets + {{- end }} + volumes: + - name: empty-dir + emptyDir: {} + {{- if .Values.auth.client.secureTransport }} + - name: certs + secret: + secretName: {{ required "A secret containing the client certificates is required" (tpl .Values.auth.client.existingSecret .) }} + defaultMode: 256 + {{- end }} + {{- if and .Values.usePasswordFiles (or .Values.auth.rbac.create .Values.auth.rbac.enabled) }} + - name: etcd-secrets + projected: + sources: + - secret: + name: {{ include "etcd.secretName" . }} + {{- end }} + - name: snapshot-volume + persistentVolumeClaim: + claimName: {{ include "etcd.disasterRecovery.pvc.name" . }} +{{- end }} diff --git a/charts/mayastor/charts/etcd/templates/extra-list.yaml b/charts/mayastor/charts/etcd/templates/extra-list.yaml new file mode 100644 index 0000000..329f5c6 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/extra-list.yaml @@ -0,0 +1,9 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- range .Values.extraDeploy }} +--- +{{ include "common.tplvalues.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/charts/mayastor/charts/etcd/templates/networkpolicy.yaml b/charts/mayastor/charts/etcd/templates/networkpolicy.yaml new file mode 100644 index 0000000..d533647 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/networkpolicy.yaml @@ -0,0 +1,84 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ template "common.capabilities.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: etcd + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: etcd + policyTypes: + - Ingress + - Egress + {{- if .Values.networkPolicy.allowExternalEgress }} + egress: + - {} + {{- else }} + egress: + # Allow dns resolution + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + # Allow outbound connections to other cluster pods + - ports: + - port: {{ .Values.containerPorts.client }} + - port: {{ .Values.containerPorts.peer }} + to: + - podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 14 }} + app.kubernetes.io/component: etcd + {{- if .Values.networkPolicy.extraEgress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraEgress "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} + ingress: + # Allow inbound connections + - ports: + - port: {{ .Values.containerPorts.client }} + - port: {{ .Values.containerPorts.peer }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ template "common.names.fullname" . }}-client: "true" + - podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 14 }} + app.kubernetes.io/component: etcd + {{- if .Values.networkPolicy.ingressNSMatchLabels }} + - namespaceSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- if .Values.networkPolicy.ingressNSPodMatchLabels }} + podSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSPodMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.metrics.enabled }} + # Allow prometheus scrapes for metrics + - ports: + - port: {{ .Values.metrics.useSeparateEndpoint | ternary .Values.containerPorts.metrics .Values.containerPorts.client }} + {{- end }} + {{- if .Values.networkPolicy.extraIngress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraIngress "context" $ ) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/etcd/templates/pdb.yaml b/charts/mayastor/charts/etcd/templates/pdb.yaml new file mode 100644 index 0000000..9380fd2 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/pdb.yaml @@ -0,0 +1,28 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.pdb.create }} +apiVersion: {{ include "common.capabilities.policy.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: etcd + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.pdb.minAvailable }} + minAvailable: {{ .Values.pdb.minAvailable }} + {{- end }} + {{- if or .Values.pdb.maxUnavailable ( not .Values.pdb.minAvailable ) }} + maxUnavailable: {{ .Values.pdb.maxUnavailable | default 1 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: etcd +{{- end }} diff --git a/charts/mayastor/charts/etcd/templates/podmonitor.yaml b/charts/mayastor/charts/etcd/templates/podmonitor.yaml new file mode 100644 index 0000000..df5c147 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/podmonitor.yaml @@ -0,0 +1,46 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.metrics.enabled .Values.metrics.podMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ ternary .Values.metrics.podMonitor.namespace (include "common.names.namespace" .) (not (empty .Values.metrics.podMonitor.namespace)) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.metrics.podMonitor.additionalLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.podMonitor.additionalLabels "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + podMetricsEndpoints: + - port: {{ .Values.metrics.useSeparateEndpoint | ternary "metrics" "client" }} + path: /metrics + {{- if .Values.metrics.podMonitor.interval }} + interval: {{ .Values.metrics.podMonitor.interval }} + {{- end }} + {{- if .Values.metrics.podMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.podMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.podMonitor.scheme }} + scheme: {{ .Values.metrics.podMonitor.scheme }} + {{- end }} + {{- if .Values.metrics.podMonitor.tlsConfig }} + tlsConfig: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.podMonitor.tlsConfig "context" $ ) | nindent 8 }} + {{- end }} + {{- if .Values.metrics.podMonitor.relabelings }} + relabelings: + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.podMonitor.relabelings "context" $) | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ include "common.names.namespace" . | quote }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: etcd +{{- end }} diff --git a/charts/mayastor/charts/etcd/templates/preupgrade-hook-job.yaml b/charts/mayastor/charts/etcd/templates/preupgrade-hook-job.yaml new file mode 100644 index 0000000..15d5ee6 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/preupgrade-hook-job.yaml @@ -0,0 +1,208 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.preUpgradeJob.enabled }} +apiVersion: {{ include "common.capabilities.job.apiVersion" . }} +kind: Job +metadata: + name: {{ include "common.names.fullname" . }}-pre-upgrade + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: etcd-pre-upgrade-job + {{- $defaultAnnotations := dict "helm.sh/hook" "pre-upgrade" "helm.sh/hook-delete-policy" "before-hook-creation" }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.preUpgradeJob.annotations .Values.commonAnnotations $defaultAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }} +spec: + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.preUpgradeJob.podLabels .Values.commonLabels ) "context" . ) }} + template: + metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }} + app.kubernetes.io/component: etcd-pre-upgrade-job + annotations: + {{- if .Values.preUpgradeJob.podAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.preUpgradeJob.podAnnotations "context" $) | nindent 8 }} + {{- end }} + {{- if (include "etcd.createConfigmap" .) }} + checksum/configuration: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if (include "etcd.token.createSecret" .) }} + checksum/token-secret: {{ include (print $.Template.BasePath "/token-secrets.yaml") . | sha256sum }} + {{- end }} + spec: + {{- include "etcd.imagePullSecrets" . | nindent 6 }} + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + {{- if .Values.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.preUpgradeJob.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.preUpgradeJob.podAffinityPreset "component" "etcd-pre-upgrade-job" "customLabels" $podLabels "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.preUpgradeJob.podAntiAffinityPreset "component" "etcd-pre-upgrade-job" "customLabels" $podLabels "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.preUpgradeJob.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" .Values.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.podSecurityContext "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.preUpgradeJob.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.preUpgradeJob.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.topologySpreadConstraints "context" .) | nindent 8 }} + {{- end }} + restartPolicy: Never + containers: + {{- $replicaCount := int .Values.replicaCount }} + {{- $clientPort := int .Values.containerPorts.client }} + {{- $etcdFullname := include "common.names.fullname" . }} + {{- $releaseNamespace := include "common.names.namespace" . }} + {{- $etcdHeadlessServiceName := (printf "%s-%s" $etcdFullname "headless" | trunc 63 | trimSuffix "-") }} + {{- $clusterDomain := .Values.clusterDomain }} + {{- $etcdClientProtocol := include "etcd.clientProtocol" . }} + - name: pre-upgrade-job + image: {{ include "etcd.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.preUpgradeJob.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.preUpgradeJob.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + command: [ "/opt/bitnami/scripts/etcd/entrypoint.sh" ] + args: [ "/opt/bitnami/scripts/etcd/preupgrade.sh" ] + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + - name: ETCD_ON_K8S + value: "yes" + - name: ETCD_DATA_DIR + value: "/bitnami/etcd/data" + {{- if or .Values.auth.rbac.create .Values.auth.rbac.enabled }} + {{- if .Values.usePasswordFiles }} + - name: ETCD_ROOT_PASSWORD_FILE + value: {{ printf "/opt/bitnami/etcd/secrets/%s" (include "etcd.secretPasswordKey" .) }} + {{- else }} + - name: ETCD_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "etcd.secretName" . }} + key: {{ include "etcd.secretPasswordKey" . }} + {{- end }} + {{- end }} + {{- $initialCluster := list }} + {{- range $e, $i := until $replicaCount }} + {{- $initialCluster = append $initialCluster (printf "%s-%d=%s://%s-%d.%s.%s.svc.%s:%d" $etcdFullname $i $etcdClientProtocol $etcdFullname $i $etcdHeadlessServiceName $releaseNamespace $clusterDomain $clientPort) }} + {{- end }} + - name: ETCD_INITIAL_CLUSTER + value: {{ join "," $initialCluster | quote }} + {{- if and .Values.auth.client.secureTransport .Values.auth.client.useAutoTLS }} + - name: ETCD_AUTO_TLS + value: "true" + {{- else if .Values.auth.client.secureTransport }} + - name: ETCD_CERT_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certFilename }}" + - name: ETCD_KEY_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certKeyFilename }}" + {{- if .Values.auth.client.enableAuthentication }} + - name: ETCD_CLIENT_CERT_AUTH + value: "true" + - name: ETCD_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename | default "ca.crt" }}" + {{- else if .Values.auth.client.caFilename }} + - name: ETCD_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename }}" + {{- else }} + - name: ETCD_EXTRA_AUTH_FLAGS + value: "--insecure-skip-tls-verify" + {{- end }} + {{- end }} + {{- if .Values.preUpgradeJob.startDelay }} + - name: ETCD_PREUPGRADE_START_DELAY + value: {{ .Values.preUpgradeJob.startDelay | quote }} + {{- end }} + {{- if .Values.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + envFrom: + {{- if .Values.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsSecret "context" $) }} + {{- end }} + {{- if .Values.preUpgradeJob.resources }} + resources: {{- include "common.tplvalues.render" (dict "value" .Values.preUpgradeJob.resources "context" $) | nindent 12 }} + {{- else if ne .Values.preUpgradeJob.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.preUpgradeJob.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + {{- if or .Values.configuration .Values.existingConfigmap }} + - name: configuration + mountPath: /opt/bitnami/etcd/conf/ + {{- else }} + - name: empty-dir + mountPath: /opt/bitnami/etcd/conf/ + subPath: app-conf-dir + {{- end }} + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + {{- if and (eq .Values.auth.token.enabled true) (eq .Values.auth.token.type "jwt") }} + - name: etcd-jwt-token + mountPath: /opt/bitnami/etcd/certs/token/ + readOnly: true + {{- end }} + {{- if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS )) }} + - name: etcd-client-certs + mountPath: /opt/bitnami/etcd/certs/client/ + readOnly: true + {{- end }} + {{- if and .Values.usePasswordFiles (or .Values.auth.rbac.create .Values.auth.rbac.enabled) }} + - name: etcd-secrets + mountPath: /opt/bitnami/etcd/secrets + {{- end }} + {{- if .Values.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + volumes: + - name: empty-dir + emptyDir: {} + {{- if or .Values.configuration .Values.existingConfigmap }} + - name: configuration + configMap: + name: {{ include "etcd.configmapName" . }} + {{- end }} + {{- if and (eq .Values.auth.token.enabled true) (eq .Values.auth.token.type "jwt") }} + - name: etcd-jwt-token + secret: + secretName: {{ include "etcd.token.secretName" . }} + defaultMode: 256 + {{- end }} + {{- if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS )) }} + - name: etcd-client-certs + secret: + secretName: {{ required "A secret containing the client certificates is required" (tpl .Values.auth.client.existingSecret .) }} + defaultMode: 256 + {{- end }} + {{- if and .Values.usePasswordFiles (or .Values.auth.rbac.create .Values.auth.rbac.enabled) }} + - name: etcd-secrets + projected: + sources: + - secret: + name: {{ include "etcd.secretName" . }} + {{- end }} + {{- if .Values.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumes "context" $) | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/etcd/templates/prometheusrule.yaml b/charts/mayastor/charts/etcd/templates/prometheusrule.yaml new file mode 100644 index 0000000..9f2631d --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/prometheusrule.yaml @@ -0,0 +1,24 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ default (include "common.names.namespace" .) .Values.metrics.prometheusRule.namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: metrics + {{- if .Values.metrics.prometheusRule.additionalLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.prometheusRule.additionalLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + groups: + - name: {{ include "common.names.fullname" . }} + rules: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.prometheusRule.rules "context" $ ) | nindent 6 }} +{{- end }} diff --git a/charts/mayastor/charts/etcd/templates/secrets.yaml b/charts/mayastor/charts/etcd/templates/secrets.yaml new file mode 100644 index 0000000..091b40e --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/secrets.yaml @@ -0,0 +1,20 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and (or .Values.auth.rbac.create .Values.auth.rbac.enabled) (not .Values.auth.rbac.existingSecret) -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "etcd.secretName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: etcd + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + {{ include "etcd.secretPasswordKey" .}}: {{ include "common.secrets.passwords.manage" (dict "secret" (include "common.names.fullname" .) "key" (include "etcd.secretPasswordKey" .) "providedValues" (list "auth.rbac.rootPassword") "context" $) }} +{{- end }} diff --git a/charts/mayastor/charts/etcd/templates/serviceaccount.yaml b/charts/mayastor/charts/etcd/templates/serviceaccount.yaml new file mode 100644 index 0000000..48ee3d2 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/serviceaccount.yaml @@ -0,0 +1,19 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "etcd.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.serviceAccount.labels .Values.commonLabels ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + {{- if or .Values.serviceAccount.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.serviceAccount.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/etcd/templates/snapshot-pvc.yaml b/charts/mayastor/charts/etcd/templates/snapshot-pvc.yaml new file mode 100644 index 0000000..8477d18 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/snapshot-pvc.yaml @@ -0,0 +1,25 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.disasterRecovery.enabled (not .Values.disasterRecovery.pvc.existingClaim) -}} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ printf "%s-snapshotter" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + annotations: + helm.sh/resource-policy: keep + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.disasterRecovery.pvc.size | quote }} + storageClassName: {{ .Values.disasterRecovery.pvc.storageClassName | quote }} +{{- end -}} diff --git a/charts/mayastor/charts/etcd/templates/statefulset.yaml b/charts/mayastor/charts/etcd/templates/statefulset.yaml new file mode 100644 index 0000000..3c78568 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/statefulset.yaml @@ -0,0 +1,470 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: etcd + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicaCount }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: etcd + serviceName: {{ printf "%s-headless" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + podManagementPolicy: {{ .Values.podManagementPolicy }} + updateStrategy: {{- include "common.tplvalues.render" (dict "value" .Values.updateStrategy "context" $ ) | nindent 4 }} + template: + metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }} + app.kubernetes.io/component: etcd + annotations: + {{- if .Values.podAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.podAnnotations "context" $) | nindent 8 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.podAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.podAnnotations "context" $) | nindent 8 }} + {{- end }} + {{- if (include "etcd.createConfigmap" .) }} + checksum/configuration: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if (include "etcd.token.createSecret" .) }} + checksum/token-secret: {{ include (print $.Template.BasePath "/token-secrets.yaml") . | sha256sum }} + {{- end }} + spec: + {{- include "etcd.imagePullSecrets" . | nindent 6 }} + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + {{- if .Values.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset "component" "etcd" "customLabels" $podLabels "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset "component" "etcd" "customLabels" $podLabels "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" .Values.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.topologySpreadConstraints "context" .) | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- if .Values.runtimeClassName }} + runtimeClassName: {{ .Values.runtimeClassName }} + {{- end }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.podSecurityContext "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.shareProcessNamespace }} + shareProcessNamespace: {{ .Values.shareProcessNamespace }} + {{- end }} + serviceAccountName: {{ include "etcd.serviceAccountName" $ | quote }} + {{- if or .Values.initContainers (and .Values.volumePermissions.enabled .Values.persistence.enabled) }} + initContainers: + {{- if .Values.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.initContainers "context" $) | nindent 8 }} + {{- end }} + {{- if and .Values.volumePermissions.enabled .Values.persistence.enabled }} + - name: volume-permissions + image: {{ include "etcd.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: + - /bin/bash + - -ec + - | + chown -R {{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.podSecurityContext.fsGroup }} /bitnami/etcd + securityContext: + runAsUser: 0 + {{- if .Values.volumePermissions.resources }} + resources: {{- include "common.tplvalues.render" (dict "value" .Values.volumePermissions.resources "context" $) | nindent 12 }} + {{- else if ne .Values.volumePermissions.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.volumePermissions.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /bitnami/etcd + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + {{- end }} + {{- end }} + containers: + {{- $replicaCount := int .Values.replicaCount }} + {{- $peerPort := int .Values.containerPorts.peer }} + {{- $etcdFullname := include "common.names.fullname" . }} + {{- $releaseNamespace := include "common.names.namespace" . }} + {{- $etcdHeadlessServiceName := (printf "%s-%s" $etcdFullname "headless" | trunc 63 | trimSuffix "-") }} + {{- $clusterDomain := .Values.clusterDomain }} + {{- $etcdPeerProtocol := include "etcd.peerProtocol" . }} + {{- $etcdClientProtocol := include "etcd.clientProtocol" . }} + - name: etcd + image: {{ include "etcd.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + {{- else if .Values.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.args "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_STS_NAME + value: {{ include "common.names.fullname" . | quote }} + - name: ETCD_ON_K8S + value: "yes" + - name: ETCD_START_FROM_SNAPSHOT + value: {{ ternary "yes" "no" .Values.startFromSnapshot.enabled | quote }} + - name: ETCD_DISASTER_RECOVERY + value: {{ ternary "yes" "no" .Values.disasterRecovery.enabled | quote }} + - name: ETCD_NAME + value: "$(MY_POD_NAME)" + - name: ETCD_DATA_DIR + value: "/bitnami/etcd/data" + - name: ETCD_LOG_LEVEL + value: {{ ternary "debug" .Values.logLevel .Values.image.debug | quote }} + - name: ALLOW_NONE_AUTHENTICATION + value: {{ ternary "yes" "no" (and (not (or .Values.auth.rbac.create .Values.auth.rbac.enabled)) .Values.auth.rbac.allowNoneAuthentication) | quote }} + {{- if or .Values.auth.rbac.create .Values.auth.rbac.enabled }} + {{- if .Values.usePasswordFiles }} + - name: ETCD_ROOT_PASSWORD_FILE + value: {{ printf "/opt/bitnami/etcd/secrets/%s" (include "etcd.secretPasswordKey" .) }} + {{- else }} + - name: ETCD_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "etcd.secretName" . }} + key: {{ include "etcd.secretPasswordKey" . }} + {{- end }} + {{- end }} + {{- if .Values.auth.token.enabled }} + - name: ETCD_AUTH_TOKEN + {{- if eq .Values.auth.token.type "jwt" }} + value: {{ printf "jwt,priv-key=/opt/bitnami/etcd/certs/token/%s,sign-method=%s,ttl=%s" .Values.auth.token.privateKey.filename .Values.auth.token.signMethod .Values.auth.token.ttl | quote }} + {{- else if eq .Values.auth.token.type "simple" }} + value: "simple" + {{- end }} + {{- end }} + - name: ETCD_ADVERTISE_CLIENT_URLS + value: "{{ $etcdClientProtocol }}://$(MY_POD_NAME).{{ $etcdHeadlessServiceName }}.{{ include "common.names.namespace" . }}.svc.{{ $clusterDomain }}:{{ .Values.containerPorts.client }}{{- if .Values.service.enabled }},{{ $etcdClientProtocol }}://{{ $etcdFullname }}.{{ include "common.names.namespace" . }}.svc.{{ $clusterDomain }}:{{ .Values.service.ports.client }}{{- end }}" + - name: ETCD_LISTEN_CLIENT_URLS + value: "{{ $etcdClientProtocol }}://0.0.0.0:{{ .Values.containerPorts.client }}" + - name: ETCD_INITIAL_ADVERTISE_PEER_URLS + value: "{{ $etcdPeerProtocol }}://$(MY_POD_NAME).{{ $etcdHeadlessServiceName }}.{{ include "common.names.namespace" . }}.svc.{{ $clusterDomain }}:{{ .Values.containerPorts.peer }}" + - name: ETCD_LISTEN_PEER_URLS + value: "{{ $etcdPeerProtocol }}://0.0.0.0:{{ .Values.containerPorts.peer }}" + {{- if .Values.metrics.useSeparateEndpoint }} + - name: ETCD_LISTEN_METRICS_URLS + value: "http://0.0.0.0:{{ .Values.containerPorts.metrics }}" + {{- end }} + {{- if .Values.autoCompactionMode }} + - name: ETCD_AUTO_COMPACTION_MODE + value: {{ .Values.autoCompactionMode | quote }} + {{- end }} + {{- if .Values.autoCompactionRetention }} + - name: ETCD_AUTO_COMPACTION_RETENTION + value: {{ .Values.autoCompactionRetention | quote }} + {{- end }} + {{- if .Values.maxProcs }} + - name: GOMAXPROCS + value: {{ .Values.maxProcs | quote }} + {{- end }} + - name: ETCD_INITIAL_CLUSTER_TOKEN + value: {{ .Values.initialClusterToken | quote }} + {{- $initialCluster := list }} + {{- range $e, $i := until $replicaCount }} + {{- $initialCluster = append $initialCluster (printf "%s-%d=%s://%s-%d.%s.%s.svc.%s:%d" $etcdFullname $i $etcdPeerProtocol $etcdFullname $i $etcdHeadlessServiceName $releaseNamespace $clusterDomain $peerPort) }} + {{- end }} + - name: ETCD_INITIAL_CLUSTER + value: {{ join "," $initialCluster | quote }} + - name: ETCD_CLUSTER_DOMAIN + value: {{ printf "%s.%s.svc.%s" $etcdHeadlessServiceName $releaseNamespace $clusterDomain | quote }} + {{- if and .Values.auth.client.secureTransport .Values.auth.client.useAutoTLS }} + - name: ETCD_AUTO_TLS + value: "true" + {{- else if .Values.auth.client.secureTransport }} + - name: ETCD_CERT_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certFilename }}" + - name: ETCD_KEY_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certKeyFilename }}" + {{- if .Values.auth.client.enableAuthentication }} + - name: ETCD_CLIENT_CERT_AUTH + value: "true" + - name: ETCD_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename | default "ca.crt" }}" + {{- else if .Values.auth.client.caFilename }} + - name: ETCD_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename | default "ca.crt" }}" + {{- end }} + {{- end }} + {{- if and .Values.auth.peer.secureTransport .Values.auth.peer.useAutoTLS }} + - name: ETCD_PEER_AUTO_TLS + value: "true" + {{- else if .Values.auth.peer.secureTransport }} + - name: ETCD_PEER_CERT_FILE + value: "/opt/bitnami/etcd/certs/peer/{{ .Values.auth.peer.certFilename }}" + - name: ETCD_PEER_KEY_FILE + value: "/opt/bitnami/etcd/certs/peer/{{ .Values.auth.peer.certKeyFilename }}" + {{- if .Values.auth.peer.enableAuthentication }} + - name: ETCD_PEER_CLIENT_CERT_AUTH + value: "true" + - name: ETCD_PEER_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/peer/{{ .Values.auth.peer.caFilename | default "ca.crt" }}" + {{- else if .Values.auth.peer.caFilename }} + - name: ETCD_PEER_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/peer/{{ .Values.auth.peer.caFilename | default "ca.crt" }}" + {{- end }} + {{- end }} + {{- if .Values.startFromSnapshot.enabled }} + - name: ETCD_INIT_SNAPSHOT_FILENAME + value: {{ .Values.startFromSnapshot.snapshotFilename | quote }} + - name: ETCD_INIT_SNAPSHOTS_DIR + value: {{ ternary "/snapshots" "/init-snapshot" (and .Values.disasterRecovery.enabled (not .Values.disasterRecovery.pvc.existingClaim)) | quote }} + {{- end }} + {{- if .Values.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + envFrom: + {{- if .Values.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsSecret "context" $) }} + {{- end }} + ports: + - name: client + containerPort: {{ .Values.containerPorts.client }} + protocol: TCP + - name: peer + containerPort: {{ .Values.containerPorts.peer }} + protocol: TCP + {{- if .Values.metrics.useSeparateEndpoint }} + - name: metrics + containerPort: {{ .Values.containerPorts.metrics }} + protocol: TCP + {{- end }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.livenessProbe.enabled }} + livenessProbe: + {{- if .Values.auth.client.secureTransport }} + exec: + command: + - /opt/bitnami/scripts/etcd/healthcheck.sh + {{- else }} + httpGet: + port: {{ .Values.metrics.useSeparateEndpoint | ternary .Values.containerPorts.metrics .Values.containerPorts.client }} + path: /livez + scheme: "HTTP" + {{- end }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.readinessProbe.enabled }} + readinessProbe: + exec: + command: + - /opt/bitnami/scripts/etcd/healthcheck.sh + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + {{- end }} + {{- if .Values.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.startupProbe.enabled }} + startupProbe: + exec: + command: + - /opt/bitnami/scripts/etcd/healthcheck.sh + initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }} + successThreshold: {{ .Values.startupProbe.successThreshold }} + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + {{- end }} + {{- if .Values.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.resources }} + resources: {{- include "common.tplvalues.render" (dict "value" .Values.resources "context" $) | nindent 12 }} + {{- else if ne .Values.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + {{- if or .Values.configuration .Values.existingConfigmap }} + - name: configuration + mountPath: /opt/bitnami/etcd/conf/ + {{- else }} + - name: empty-dir + mountPath: /opt/bitnami/etcd/conf/ + subPath: app-conf-dir + {{- end }} + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + - name: data + mountPath: /bitnami/etcd + {{- if and (eq .Values.auth.token.enabled true) (eq .Values.auth.token.type "jwt") }} + - name: etcd-jwt-token + mountPath: /opt/bitnami/etcd/certs/token/ + readOnly: true + {{- end }} + {{- if or (and .Values.startFromSnapshot.enabled (not .Values.disasterRecovery.enabled)) (and .Values.disasterRecovery.enabled .Values.startFromSnapshot.enabled .Values.disasterRecovery.pvc.existingClaim) }} + - name: init-snapshot-volume + mountPath: /init-snapshot + {{- end }} + {{- if .Values.disasterRecovery.enabled }} + - name: snapshot-volume + mountPath: /snapshots + {{- if .Values.disasterRecovery.pvc.subPath }} + subPath: {{ .Values.disasterRecovery.pvc.subPath }} + {{- end }} + {{- end }} + {{- if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS )) }} + - name: etcd-client-certs + mountPath: /opt/bitnami/etcd/certs/client/ + readOnly: true + {{- end }} + {{- if or .Values.auth.peer.enableAuthentication (and .Values.auth.peer.secureTransport (not .Values.auth.peer.useAutoTLS )) }} + - name: etcd-peer-certs + mountPath: /opt/bitnami/etcd/certs/peer/ + readOnly: true + {{- end }} + {{- if and .Values.usePasswordFiles (or .Values.auth.rbac.create .Values.auth.rbac.enabled) }} + - name: etcd-secrets + mountPath: /opt/bitnami/etcd/secrets + {{- end }} + {{- if .Values.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + - name: empty-dir + emptyDir: {} + {{- if or .Values.configuration .Values.existingConfigmap }} + - name: configuration + configMap: + name: {{ include "etcd.configmapName" . }} + {{- end }} + {{- if and (eq .Values.auth.token.enabled true) (eq .Values.auth.token.type "jwt") }} + - name: etcd-jwt-token + secret: + secretName: {{ include "etcd.token.secretName" . }} + defaultMode: 256 + {{- end }} + {{- if or (and .Values.startFromSnapshot.enabled (not .Values.disasterRecovery.enabled)) (and .Values.disasterRecovery.enabled .Values.startFromSnapshot.enabled .Values.disasterRecovery.pvc.existingClaim) }} + - name: init-snapshot-volume + persistentVolumeClaim: + claimName: {{ .Values.startFromSnapshot.existingClaim }} + {{- end }} + {{- if or .Values.disasterRecovery.enabled (and .Values.disasterRecovery.enabled .Values.startFromSnapshot.enabled) }} + - name: snapshot-volume + persistentVolumeClaim: + claimName: {{ include "etcd.disasterRecovery.pvc.name" . }} + {{- end }} + {{- if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS )) }} + - name: etcd-client-certs + secret: + secretName: {{ required "A secret containing the client certificates is required" (tpl .Values.auth.client.existingSecret .) }} + defaultMode: 256 + {{- end }} + {{- if or .Values.auth.peer.enableAuthentication (and .Values.auth.peer.secureTransport (not .Values.auth.peer.useAutoTLS )) }} + - name: etcd-peer-certs + secret: + secretName: {{ required "A secret containing the peer certificates is required" (tpl .Values.auth.peer.existingSecret .) }} + defaultMode: 256 + {{- end }} + {{- if and .Values.usePasswordFiles (or .Values.auth.rbac.create .Values.auth.rbac.enabled) }} + - name: etcd-secrets + projected: + sources: + - secret: + name: {{ include "etcd.secretName" . }} + {{- end }} + {{- if .Values.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumes "context" $) | nindent 8 }} + {{- end }} + {{- if not .Values.persistence.enabled }} + - name: data + emptyDir: {} + {{- else }} + {{- if .Values.persistentVolumeClaimRetentionPolicy.enabled }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.persistentVolumeClaimRetentionPolicy.whenDeleted }} + whenScaled: {{ .Values.persistentVolumeClaimRetentionPolicy.whenScaled }} + {{- end }} + volumeClaimTemplates: + - metadata: + name: data + {{- if .Values.persistence.annotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.persistence.annotations "context" $) | nindent 10 }} + {{- end }} + {{- if .Values.persistence.labels }} + labels: {{- include "common.tplvalues.render" ( dict "value" .Values.persistence.labels "context" $) | nindent 10 }} + {{- end }} + spec: + accessModes: + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{- if .Values.persistence.selector }} + selector: {{- include "common.tplvalues.render" ( dict "value" .Values.persistence.selector "context" $) | nindent 10 }} + {{- end }} + {{ include "common.storage.class" (dict "persistence" .Values.persistence "global" .Values.global) }} + {{- if .Values.extraVolumeClaimTemplates }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumeClaimTemplates "context" $) | nindent 4 }} + {{- end }} + {{- end }} diff --git a/charts/mayastor/charts/etcd/templates/svc-headless.yaml b/charts/mayastor/charts/etcd/templates/svc-headless.yaml new file mode 100644 index 0000000..4e47160 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/svc-headless.yaml @@ -0,0 +1,57 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: v1 +kind: Service +metadata: + name: {{ printf "%s-headless" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: etcd + annotations: + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" + {{- if or .Values.service.headless.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.service.headless.annotations .Values.commonAnnotations ) "context" . ) }} + {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + publishNotReadyAddresses: true + ports: + {{- if .Values.service.clientPortNameOverride }} + {{- if .Values.auth.client.secureTransport }} + - name: {{ .Values.service.clientPortNameOverride }}-ssl + {{- else }} + - name: {{ .Values.service.clientPortNameOverride }} + {{- end }} + {{- else }} + - name: client + {{- end }} + port: {{ .Values.containerPorts.client }} + targetPort: client + {{- if .Values.service.peerPortNameOverride }} + {{- if .Values.auth.peer.secureTransport }} + - name: {{ .Values.service.peerPortNameOverride }}-ssl + {{- else }} + - name: {{ .Values.service.peerPortNameOverride }} + {{- end }} + {{- else }} + - name: peer + {{- end }} + port: {{ .Values.containerPorts.peer }} + targetPort: peer + {{- if .Values.metrics.useSeparateEndpoint }} + {{- if .Values.service.metricsPortNameOverride }} + - name: {{ .Values.service.metricsPortNameOverride }} + {{- else }} + - name: metrics + {{- end }} + port: {{ .Values.containerPorts.metrics }} + targetPort: metrics + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: etcd diff --git a/charts/mayastor/charts/etcd/templates/svc.yaml b/charts/mayastor/charts/etcd/templates/svc.yaml new file mode 100644 index 0000000..1d53466 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/svc.yaml @@ -0,0 +1,77 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: etcd + {{- if or .Values.service.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.service.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- if .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + {{- if (or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort")) }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP)) }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerClass)) }} + loadBalancerClass: {{ .Values.service.loadBalancerClass }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerSourceRanges)) }} + loadBalancerSourceRanges: {{- toYaml .Values.service.loadBalancerSourceRanges | nindent 4 }} + {{- end }} + {{- if .Values.service.externalIPs }} + externalIPs: {{- toYaml .Values.service.externalIPs | nindent 4 }} + {{- end }} + {{- if .Values.service.sessionAffinity }} + sessionAffinity: {{ .Values.service.sessionAffinity }} + {{- end }} + {{- if .Values.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + - name: {{ default "client" .Values.service.clientPortNameOverride | quote }} + port: {{ .Values.service.ports.client }} + targetPort: client + {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty (.Values.service.nodePorts.client))) }} + nodePort: {{ .Values.service.nodePorts.client }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + - name: {{ default "peer" .Values.service.peerPortNameOverride | quote }} + port: {{ .Values.service.ports.peer }} + targetPort: peer + {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty (.Values.service.nodePorts.peer))) }} + nodePort: {{ .Values.service.nodePorts.peer }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if .Values.metrics.useSeparateEndpoint }} + - name: {{ default "metrics" .Values.service.metricsPortNameOverride | quote }} + port: {{ .Values.service.ports.metrics }} + targetPort: metrics + {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty (.Values.service.nodePorts.metrics))) }} + nodePort: {{ .Values.service.nodePorts.metrics }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- end }} + {{- if .Values.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: etcd +{{- end }} diff --git a/charts/mayastor/charts/etcd/templates/token-secrets.yaml b/charts/mayastor/charts/etcd/templates/token-secrets.yaml new file mode 100644 index 0000000..cd56f47 --- /dev/null +++ b/charts/mayastor/charts/etcd/templates/token-secrets.yaml @@ -0,0 +1,19 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if (include "etcd.token.createSecret" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "etcd.token.secretName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + jwt-token.pem: {{ include "etcd.token.jwtToken" . | b64enc | quote }} +{{- end }} diff --git a/charts/mayastor/charts/etcd/values.yaml b/charts/mayastor/charts/etcd/values.yaml new file mode 100644 index 0000000..85ab8fd --- /dev/null +++ b/charts/mayastor/charts/etcd/values.yaml @@ -0,0 +1,1273 @@ +# Copyright Broadcom, Inc. All Rights Reserved. +# SPDX-License-Identifier: APACHE-2.0 + +## @section Global parameters +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass +## + +## @param global.imageRegistry Global Docker image registry +## @param global.imagePullSecrets [array] Global Docker registry secret names as an array +## @param global.defaultStorageClass Global default StorageClass for Persistent Volume(s) +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + defaultStorageClass: "" + ## Security parameters + ## + security: + ## @param global.security.allowInsecureImages Allows skipping image verification + allowInsecureImages: false + ## Compatibility adaptations for Kubernetes platforms + ## + compatibility: + ## Compatibility adaptations for Openshift + ## + openshift: + ## @param global.compatibility.openshift.adaptSecurityContext Adapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation) + ## + adaptSecurityContext: auto +## @section Common parameters +## + +## @param kubeVersion Force target Kubernetes version (using Helm capabilities if not set) +## +kubeVersion: "" +## @param nameOverride String to partially override common.names.fullname template (will maintain the release name) +## +nameOverride: "" +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: "" +## @param namespaceOverride String to fully override common.names.namespace template +## +namespaceOverride: "" +## @param commonLabels [object] Labels to add to all deployed objects +## +commonLabels: {} +## @param commonAnnotations [object] Annotations to add to all deployed objects +## +commonAnnotations: {} +## @param clusterDomain Default Kubernetes cluster domain +## +clusterDomain: cluster.local +## @param extraDeploy [array] Array of extra objects to deploy with the release +## +extraDeploy: [] +## @param usePasswordFiles Mount credentials as files instead of using environment variables +## +usePasswordFiles: true +## Enable diagnostic mode in the deployment +## +diagnosticMode: + ## @param diagnosticMode.enabled Enable diagnostic mode (all probes will be disabled and the command will be overridden) + ## + enabled: false + ## @param diagnosticMode.command Command to override all containers in the deployment + ## + command: + - sleep + ## @param diagnosticMode.args Args to override all containers in the deployment + ## + args: + - infinity +## @section etcd parameters +## + +## Bitnami etcd image version +## ref: https://hub.docker.com/r/bitnami/etcd/tags/ +## @param image.registry [default: REGISTRY_NAME] etcd image registry +## @param image.repository [default: REPOSITORY_NAME/etcd] etcd image name +## @skip image.tag etcd image tag +## @param image.digest etcd image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag +## +image: + registry: docker.io + repository: bitnami/etcd + tag: 3.6.4-debian-12-r0 + digest: "" + ## @param image.pullPolicy etcd image pull policy + ## Specify a imagePullPolicy + ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images + ## + pullPolicy: IfNotPresent + ## @param image.pullSecrets [array] etcd image pull secrets + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param image.debug Enable image debug mode + ## Set to true if you would like to see extra information on logs + ## + debug: false +## Authentication parameters +## +auth: + ## Role-based access control parameters + ## ref: https://etcd.io/docs/current/op-guide/authentication/ + ## + rbac: + ## @param auth.rbac.create Switch to enable RBAC authentication + ## + create: true + ## @param auth.rbac.allowNoneAuthentication Allow to use etcd without configuring RBAC authentication + ## + allowNoneAuthentication: true + ## @param auth.rbac.rootPassword Root user password. The root user is always `root` + ## + rootPassword: "" + ## @param auth.rbac.existingSecret Name of the existing secret containing credentials for the root user + ## + existingSecret: "" + ## @param auth.rbac.existingSecretPasswordKey Name of key containing password to be retrieved from the existing secret + ## + existingSecretPasswordKey: "" + ## Authentication token + ## ref: https://etcd.io/docs/latest/learning/design-auth-v3/#two-types-of-tokens-simple-and-jwt + ## + token: + ## @param auth.token.enabled Enables token authentication + ## + enabled: true + ## @param auth.token.type Authentication token type. Allowed values: 'simple' or 'jwt' + ## ref: https://etcd.io/docs/latest/op-guide/configuration/#--auth-token + ## + type: jwt + ## @param auth.token.privateKey.filename Name of the file containing the private key for signing the JWT token + ## @param auth.token.privateKey.existingSecret Name of the existing secret containing the private key for signing the JWT token + ## NOTE: Ignored if auth.token.type=simple + ## NOTE: A secret containing a private key will be auto-generated if an existing one is not provided. + ## + privateKey: + filename: jwt-token.pem + existingSecret: "" + ## @param auth.token.signMethod JWT token sign method + ## NOTE: Ignored if auth.token.type=simple + ## + signMethod: RS256 + ## @param auth.token.ttl JWT token TTL + ## NOTE: Ignored if auth.token.type=simple + ## + ttl: 10m + ## TLS authentication for client-to-server communications + ## ref: https://etcd.io/docs/current/op-guide/security/ + ## + client: + ## @param auth.client.secureTransport Switch to encrypt client-to-server communications using TLS certificates + ## + secureTransport: false + ## @param auth.client.useAutoTLS Switch to automatically create the TLS certificates + ## + useAutoTLS: false + ## @param auth.client.existingSecret Name of the existing secret containing the TLS certificates for client-to-server communications + ## + existingSecret: "" + ## @param auth.client.enableAuthentication Switch to enable host authentication using TLS certificates. Requires existing secret + ## + enableAuthentication: false + ## @param auth.client.certFilename Name of the file containing the client certificate + ## + certFilename: cert.pem + ## @param auth.client.certKeyFilename Name of the file containing the client certificate private key + ## + certKeyFilename: key.pem + ## @param auth.client.caFilename Name of the file containing the client CA certificate + ## If not specified and `auth.client.enableAuthentication=true` or `auth.rbac.enabled=true`, the default is is `ca.crt` + ## + caFilename: "" + ## TLS authentication for server-to-server communications + ## ref: https://etcd.io/docs/current/op-guide/security/ + ## + peer: + ## @param auth.peer.secureTransport Switch to encrypt server-to-server communications using TLS certificates + ## + secureTransport: false + ## @param auth.peer.useAutoTLS Switch to automatically create the TLS certificates + ## + useAutoTLS: false + ## @param auth.peer.existingSecret Name of the existing secret containing the TLS certificates for server-to-server communications + ## + existingSecret: "" + ## @param auth.peer.enableAuthentication Switch to enable host authentication using TLS certificates. Requires existing secret + ## + enableAuthentication: false + ## @param auth.peer.certFilename Name of the file containing the peer certificate + ## + certFilename: cert.pem + ## @param auth.peer.certKeyFilename Name of the file containing the peer certificate private key + ## + certKeyFilename: key.pem + ## @param auth.peer.caFilename Name of the file containing the peer CA certificate + ## If not specified and `auth.peer.enableAuthentication=true` or `rbac.enabled=true`, the default is is `ca.crt` + ## + caFilename: "" +## @param autoCompactionMode Auto compaction mode, by default periodic. Valid values: "periodic", "revision". +## - 'periodic' for duration based retention, defaulting to hours if no time unit is provided (e.g. 5m). +## - 'revision' for revision number based retention. +## +autoCompactionMode: "" +## @param autoCompactionRetention Auto compaction retention for mvcc key value store in hour, by default 0, means disabled +## +autoCompactionRetention: "" +## @param initialClusterToken Initial cluster token. Can be used to protect etcd from cross-cluster-interaction, which might corrupt the clusters. +## If spinning up multiple clusters (or creating and destroying a single cluster) +## with same configuration for testing purpose, it is highly recommended that each cluster is given a unique initial-cluster-token. +## By doing this, etcd can generate unique cluster IDs and member IDs for the clusters even if they otherwise have the exact same configuration. +## +initialClusterToken: "etcd-cluster-k8s" +## @param logLevel Sets the log level for the etcd process. Allowed values: 'debug', 'info', 'warn', 'error', 'panic', 'fatal' +## +logLevel: "info" +## @param maxProcs Limits the number of operating system threads that can execute user-level +## Go code simultaneously by setting GOMAXPROCS environment variable +## ref: https://golang.org/pkg/runtime +## +maxProcs: "" +## @param configuration etcd configuration. Specify content for etcd.conf.yml +## e.g: +## configuration: |- +## foo: bar +## baz: +## +configuration: "" +## @param existingConfigmap Existing ConfigMap with etcd configuration +## NOTE: When it's set the configuration parameter is ignored +## +existingConfigmap: "" +## @param extraEnvVars [array] Extra environment variables to be set on etcd container +## e.g: +## extraEnvVars: +## - name: FOO +## value: "bar" +## +extraEnvVars: [] +## @param extraEnvVarsCM Name of existing ConfigMap containing extra env vars +## +extraEnvVarsCM: "" +## @param extraEnvVarsSecret Name of existing Secret containing extra env vars +## +extraEnvVarsSecret: "" +## @param command [array] Default container command (useful when using custom images) +## +command: [] +## @param args [array] Default container args (useful when using custom images) +## +args: [] +## @section etcd statefulset parameters +## + +## @param replicaCount Number of etcd replicas to deploy +## +replicaCount: 1 +## Update strategy +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies +## @param updateStrategy.type Update strategy type, can be set to RollingUpdate or OnDelete. +## +updateStrategy: + type: RollingUpdate +## @param podManagementPolicy Pod management policy for the etcd statefulset +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies +## +podManagementPolicy: Parallel +## @param automountServiceAccountToken Mount Service Account token in pod +## +automountServiceAccountToken: false +## @param hostAliases [array] etcd pod host aliases +## ref: https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ +## +hostAliases: [] +## @param lifecycleHooks [object] Override default etcd container hooks +## +lifecycleHooks: {} +## etcd container ports to open +## @param containerPorts.client Client port to expose at container level +## @param containerPorts.peer Peer port to expose at container level +## @param containerPorts.metrics Metrics port to expose at container level when metrics.useSeparateEndpoint is true +## +containerPorts: + client: 2379 + peer: 2380 + metrics: 9090 +## etcd pods' Security Context +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod +## @param podSecurityContext.enabled Enabled etcd pods' Security Context +## @param podSecurityContext.fsGroupChangePolicy Set filesystem group change policy +## @param podSecurityContext.sysctls Set kernel settings using the sysctl interface +## @param podSecurityContext.supplementalGroups Set filesystem extra groups +## @param podSecurityContext.fsGroup Set etcd pod's Security Context fsGroup +## +podSecurityContext: + enabled: true + fsGroupChangePolicy: Always + sysctls: [] + supplementalGroups: [] + fsGroup: 1001 +## etcd containers' SecurityContext +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container +## @param containerSecurityContext.enabled Enabled etcd containers' Security Context +## @param containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in container +## @param containerSecurityContext.runAsUser Set etcd containers' Security Context runAsUser +## @param containerSecurityContext.runAsGroup Set etcd containers' Security Context runAsUser +## @param containerSecurityContext.runAsNonRoot Set Controller container's Security Context runAsNonRoot +## @param containerSecurityContext.privileged Set primary container's Security Context privileged +## @param containerSecurityContext.allowPrivilegeEscalation Set primary container's Security Context allowPrivilegeEscalation +## @param containerSecurityContext.readOnlyRootFilesystem Set container's Security Context readOnlyRootFilesystem +## @param containerSecurityContext.capabilities.drop List of capabilities to be dropped +## @param containerSecurityContext.seccompProfile.type Set container's Security Context seccomp profile +## +containerSecurityContext: + enabled: true + seLinuxOptions: {} + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + privileged: false + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" +## etcd containers' resource requests and limits +## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ +## We usually recommend not to specify default resources and to leave this as a conscious +## choice for the user. This also increases chances charts run on environments with little +## resources, such as Minikube. If you do want to specify resources, uncomment the following +## lines, adjust them as necessary, and remove the curly braces after 'resources:'. +## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). +## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 +## +resourcesPreset: "micro" +## @param resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) +## Example: +## resources: +## requests: +## cpu: 2 +## memory: 512Mi +## limits: +## cpu: 3 +## memory: 1024Mi +## +resources: {} +## Configure extra options for liveness probe +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes +## @param livenessProbe.enabled Enable livenessProbe +## @param livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe +## @param livenessProbe.periodSeconds Period seconds for livenessProbe +## @param livenessProbe.timeoutSeconds Timeout seconds for livenessProbe +## @param livenessProbe.failureThreshold Failure threshold for livenessProbe +## @param livenessProbe.successThreshold Success threshold for livenessProbe +## +livenessProbe: + enabled: true + initialDelaySeconds: 60 + periodSeconds: 30 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 +## Configure extra options for readiness probe +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes +## @param readinessProbe.enabled Enable readinessProbe +## @param readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe +## @param readinessProbe.periodSeconds Period seconds for readinessProbe +## @param readinessProbe.timeoutSeconds Timeout seconds for readinessProbe +## @param readinessProbe.failureThreshold Failure threshold for readinessProbe +## @param readinessProbe.successThreshold Success threshold for readinessProbe +## +readinessProbe: + enabled: true + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 +## Configure extra options for liveness probe +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes +## @param startupProbe.enabled Enable startupProbe +## @param startupProbe.initialDelaySeconds Initial delay seconds for startupProbe +## @param startupProbe.periodSeconds Period seconds for startupProbe +## @param startupProbe.timeoutSeconds Timeout seconds for startupProbe +## @param startupProbe.failureThreshold Failure threshold for startupProbe +## @param startupProbe.successThreshold Success threshold for startupProbe +## +startupProbe: + enabled: false + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 60 +## @param customLivenessProbe [object] Override default liveness probe +## +customLivenessProbe: {} +## @param customReadinessProbe [object] Override default readiness probe +## +customReadinessProbe: {} +## @param customStartupProbe [object] Override default startup probe +## +customStartupProbe: {} +## @param extraVolumes [array] Optionally specify extra list of additional volumes for etcd pods +## +extraVolumes: [] +## @param extraVolumeMounts [array] Optionally specify extra list of additional volumeMounts for etcd container(s) +## +extraVolumeMounts: [] +## @param extraVolumeClaimTemplates [array] Optionally specify extra list of additional volumeClaimTemplates for etcd container(s) +## +extraVolumeClaimTemplates: [] +## @param initContainers [array] Add additional init containers to the etcd pods +## e.g: +## initContainers: +## - name: your-image-name +## image: your-image +## imagePullPolicy: Always +## ports: +## - name: portname +## containerPort: 1234 +## +initContainers: [] +## @param sidecars [array] Add additional sidecar containers to the etcd pods +## e.g: +## sidecars: +## - name: your-image-name +## image: your-image +## imagePullPolicy: Always +## ports: +## - name: portname +## containerPort: 1234 +## +sidecars: [] +## @param podAnnotations [object] Annotations for etcd pods +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +## +podAnnotations: {} +## @param podLabels [object] Extra labels for etcd pods +## Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +## +podLabels: {} +## @param podAffinityPreset Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAffinityPreset: "" +## @param podAntiAffinityPreset Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAntiAffinityPreset: soft +## Node affinity preset +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity +## @param nodeAffinityPreset.type Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## @param nodeAffinityPreset.key Node label key to match. Ignored if `affinity` is set. +## @param nodeAffinityPreset.values [array] Node label values to match. Ignored if `affinity` is set. +## +nodeAffinityPreset: + type: "" + ## e.g: + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## e.g: + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] +## @param affinity [object] Affinity for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set +## +affinity: {} +## @param nodeSelector [object] Node labels for pod assignment +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ +## +nodeSelector: {} +## @param tolerations [array] Tolerations for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] +## @param terminationGracePeriodSeconds Seconds the pod needs to gracefully terminate +## ref: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution +## +terminationGracePeriodSeconds: "" +## @param schedulerName Name of the k8s scheduler (other than default) +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +schedulerName: "" +## @param priorityClassName Name of the priority class to be used by etcd pods +## Priority class needs to be created beforehand +## Ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ +## +priorityClassName: "" +## @param runtimeClassName Name of the runtime class to be used by pod(s) +## ref: https://kubernetes.io/docs/concepts/containers/runtime-class/ +## +runtimeClassName: "" +## @param shareProcessNamespace Enable shared process namespace in a pod. +## If set to false (default), each container will run in separate namespace, etcd will have PID=1. +## If set to true, the /pause will run as init process and will reap any zombie PIDs, +## for example, generated by a custom exec probe running longer than a probe timeoutSeconds. +## Enable this only if customLivenessProbe or customReadinessProbe is used and zombie PIDs are accumulating. +## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/share-process-namespace/ +## +shareProcessNamespace: false +## @param topologySpreadConstraints Topology Spread Constraints for pod assignment +## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +## The value is evaluated as a template +## +topologySpreadConstraints: [] +## persistentVolumeClaimRetentionPolicy +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#persistentvolumeclaim-retention +## @param persistentVolumeClaimRetentionPolicy.enabled Controls if and how PVCs are deleted during the lifecycle of a StatefulSet +## @param persistentVolumeClaimRetentionPolicy.whenScaled Volume retention behavior when the replica count of the StatefulSet is reduced +## @param persistentVolumeClaimRetentionPolicy.whenDeleted Volume retention behavior that applies when the StatefulSet is deleted +persistentVolumeClaimRetentionPolicy: + enabled: false + whenScaled: Retain + whenDeleted: Retain +## @section Traffic exposure parameters +## + +service: + ## @param service.type Kubernetes Service type + ## + type: ClusterIP + ## @param service.enabled create second service if equal true + ## + enabled: true + ## @param service.clusterIP Kubernetes service Cluster IP + ## e.g.: + ## clusterIP: None + ## + clusterIP: "" + ## @param service.ports.client etcd client port + ## @param service.ports.peer etcd peer port + ## @param service.ports.metrics etcd metrics port when metrics.useSeparateEndpoint is true + ## + ports: + client: 2379 + peer: 2380 + metrics: 9090 + ## @param service.nodePorts.client Specify the nodePort client value for the LoadBalancer and NodePort service types. + ## @param service.nodePorts.peer Specify the nodePort peer value for the LoadBalancer and NodePort service types. + ## @param service.nodePorts.metrics Specify the nodePort metrics value for the LoadBalancer and NodePort service types. The metrics port is only exposed when metrics.useSeparateEndpoint is true. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + nodePorts: + client: "" + peer: "" + metrics: "" + ## @param service.clientPortNameOverride etcd client port name override + ## + clientPortNameOverride: "" + ## @param service.peerPortNameOverride etcd peer port name override + ## + peerPortNameOverride: "" + ## @param service.metricsPortNameOverride etcd metrics port name override. The metrics port is only exposed when metrics.useSeparateEndpoint is true. + ## + metricsPortNameOverride: "" + ## @param service.loadBalancerIP loadBalancerIP for the etcd service (optional, cloud specific) + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-loadbalancer + ## + loadBalancerIP: "" + ## @param service.loadBalancerClass loadBalancerClass for the etcd service (optional, cloud specific) + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#load-balancer-class + ## + loadBalancerClass: "" + ## @param service.loadBalancerSourceRanges [array] Load Balancer source ranges + ## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## e.g: + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param service.externalIPs [array] External IPs + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips + ## + externalIPs: [] + ## @param service.externalTrafficPolicy %%MAIN_CONTAINER_NAME%% service external traffic policy + ## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param service.annotations [object] Additional annotations for the etcd service + ## + annotations: {} + ## @param service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} + ## Headless service properties + ## + headless: + ## @param service.headless.annotations Annotations for the headless service. + ## + annotations: {} +## @section Persistence parameters +## + +## Enable persistence using Persistent Volume Claims +## ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/ +## +persistence: + ## @param persistence.enabled If true, use a Persistent Volume Claim. If false, use emptyDir. + ## + enabled: true + ## @param persistence.storageClass Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + ## + ## @param persistence.annotations [object] Annotations for the PVC + ## + annotations: {} + ## @param persistence.labels [object] Labels for the PVC + ## + labels: {} + ## @param persistence.accessModes Persistent Volume Access Modes + ## + accessModes: + - ReadWriteOnce + ## @param persistence.size PVC Storage Request for etcd data volume + ## + size: 8Gi + ## @param persistence.selector [object] Selector to match an existing Persistent Volume + ## ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector + ## + selector: {} +## @section Volume Permissions parameters +## + +## Init containers parameters: +## volumePermissions: Change the owner and group of the persistent volume mountpoint to runAsUser:fsGroup values from the securityContext section. +## +volumePermissions: + ## @param volumePermissions.enabled Enable init container that changes the owner and group of the persistent volume(s) mountpoint to `runAsUser:fsGroup` + ## + enabled: false + ## @param volumePermissions.image.registry [default: REGISTRY_NAME] Init container volume-permissions image registry + ## @param volumePermissions.image.repository [default: REPOSITORY_NAME/os-shell] Init container volume-permissions image name + ## @skip volumePermissions.image.tag Init container volume-permissions image tag + ## @param volumePermissions.image.digest Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## + image: + registry: docker.io + repository: bitnami/os-shell + tag: 12-debian-12-r49 + digest: "" + ## @param volumePermissions.image.pullPolicy Init container volume-permissions image pull policy + ## + pullPolicy: IfNotPresent + ## @param volumePermissions.image.pullSecrets [array] Specify docker-registry secret names as an array + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Init container' resource requests and limits + ## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## We usually recommend not to specify default resources and to leave this as a conscious + ## choice for the user. This also increases chances charts run on environments with little + ## resources, such as Minikube. If you do want to specify resources, uncomment the following + ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. + ## @param volumePermissions.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "nano" + ## @param volumePermissions.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## + resources: {} +## @section Network Policy parameters +## ref: https://kubernetes.io/docs/concepts/services-networking/network-policies/ +## +networkPolicy: + ## @param networkPolicy.enabled Enable creation of NetworkPolicy resources + ## + enabled: true + ## @param networkPolicy.allowExternal Don't require client label for connections + ## When set to false, only pods with the correct client label will have network access to the ports + ## etcd is listening on. When true, etcd will accept connections from any source + ## (with the correct destination port). + ## + allowExternal: true + ## @param networkPolicy.allowExternalEgress Allow the pod to access any range of port and all destinations. + ## + allowExternalEgress: true + ## @param networkPolicy.extraIngress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraIngress: + ## - ports: + ## - port: 1234 + ## from: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + ## + extraIngress: [] + ## @param networkPolicy.extraEgress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraEgress: + ## - ports: + ## - port: 1234 + ## to: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + ## + extraEgress: [] + ## @param networkPolicy.ingressNSMatchLabels [object] Labels to match to allow traffic from other namespaces + ## @param networkPolicy.ingressNSPodMatchLabels [object] Pod labels to match to allow traffic from other namespaces + ## + ingressNSMatchLabels: {} + ingressNSPodMatchLabels: {} +## @section Metrics parameters +## +metrics: + ## @param metrics.enabled Expose etcd metrics + ## + enabled: false + ## @param metrics.useSeparateEndpoint Use a separate endpoint for exposing metrics + # + useSeparateEndpoint: false + ## @param metrics.podAnnotations [object] Annotations for the Prometheus metrics on etcd pods + ## + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.metrics.useSeparateEndpoint | ternary .Values.containerPorts.metrics .Values.containerPorts.client }}" + ## Prometheus Service Monitor + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## + podMonitor: + ## @param metrics.podMonitor.enabled Create PodMonitor Resource for scraping metrics using PrometheusOperator + ## + enabled: false + ## @param metrics.podMonitor.namespace Namespace in which Prometheus is running + ## + namespace: monitoring + ## @param metrics.podMonitor.interval Specify the interval at which metrics should be scraped + ## + interval: 30s + ## @param metrics.podMonitor.scrapeTimeout Specify the timeout after which the scrape is ended + ## + scrapeTimeout: 30s + ## @param metrics.podMonitor.additionalLabels [object] Additional labels that can be used so PodMonitors will be discovered by Prometheus + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec + ## + additionalLabels: {} + ## @param metrics.podMonitor.scheme Scheme to use for scraping + ## + scheme: http + ## @param metrics.podMonitor.tlsConfig [object] TLS configuration used for scrape endpoints used by Prometheus + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#tlsconfig + ## e.g: + ## tlsConfig: + ## ca: + ## secret: + ## name: existingSecretName + ## + tlsConfig: {} + ## @param metrics.podMonitor.relabelings [array] Prometheus relabeling rules + ## + relabelings: [] + ## Prometheus Operator PrometheusRule configuration + ## + prometheusRule: + ## @param metrics.prometheusRule.enabled Create a Prometheus Operator PrometheusRule (also requires `metrics.enabled` to be `true` and `metrics.prometheusRule.rules`) + ## + enabled: false + ## @param metrics.prometheusRule.namespace Namespace for the PrometheusRule Resource (defaults to the Release Namespace) + ## + namespace: "" + ## @param metrics.prometheusRule.additionalLabels Additional labels that can be used so PrometheusRule will be discovered by Prometheus + ## + additionalLabels: {} + ## @param metrics.prometheusRule.rules Prometheus Rule definitions + # - alert: ETCD has no leader + # annotations: + # summary: "ETCD has no leader" + # description: "pod {{`{{`}} $labels.pod {{`}}`}} state error, can't connect leader" + # for: 1m + # expr: etcd_server_has_leader == 0 + # labels: + # severity: critical + # group: PaaS + ## + rules: [] +## @section Snapshotting parameters +## + +## Start a new etcd cluster recovering the data from an existing snapshot before bootstrapping +## +startFromSnapshot: + ## @param startFromSnapshot.enabled Initialize new cluster recovering an existing snapshot + ## + enabled: false + ## @param startFromSnapshot.existingClaim Existing PVC containing the etcd snapshot + ## + existingClaim: "" + ## @param startFromSnapshot.snapshotFilename Snapshot filename + ## + snapshotFilename: "" +## Enable auto disaster recovery by periodically snapshotting the keyspace: +## - It creates a cronjob to periodically snapshotting the keyspace +## - It also creates a ReadWriteMany PVC to store the snapshots +## If the cluster permanently loses more than (N-1)/2 members, it tries to +## recover itself from the last available snapshot. +## +disasterRecovery: + ## @param disasterRecovery.enabled Enable auto disaster recovery by periodically snapshotting the keyspace + ## + enabled: false + cronjob: + ## @param disasterRecovery.cronjob.schedule Schedule in Cron format to save snapshots + ## See https://en.wikipedia.org/wiki/Cron + ## + schedule: "*/30 * * * *" + ## @param disasterRecovery.cronjob.historyLimit Number of successful finished jobs to retain + ## + historyLimit: 1 + ## @param disasterRecovery.cronjob.snapshotHistoryLimit Number of etcd snapshots to retain, tagged by date + ## + snapshotHistoryLimit: 1 + ## @param disasterRecovery.cronjob.snapshotsDir Directory to store snapshots + ## + snapshotsDir: "/snapshots" + ## @param disasterRecovery.cronjob.podAnnotations [object] Pod annotations for cronjob pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## K8s Security Context for Snapshotter cronjob pods + ## https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## @param disasterRecovery.cronjob.podSecurityContext.enabled Enable security context for Snapshotter pods + ## @param disasterRecovery.cronjob.podSecurityContext.fsGroupChangePolicy Set filesystem group change policy + ## @param disasterRecovery.cronjob.podSecurityContext.sysctls Set kernel settings using the sysctl interface + ## @param disasterRecovery.cronjob.podSecurityContext.supplementalGroups Set filesystem extra groups + ## @param disasterRecovery.cronjob.podSecurityContext.fsGroup Group ID for the Snapshotter filesystem + ## + podSecurityContext: + enabled: true + fsGroupChangePolicy: Always + sysctls: [] + supplementalGroups: [] + fsGroup: 1001 + ## Configure container security context for Snapshotter cronjob containers + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param disasterRecovery.cronjob.containerSecurityContext.enabled Enabled containers' Security Context + ## @param disasterRecovery.cronjob.containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in container + ## @param disasterRecovery.cronjob.containerSecurityContext.runAsUser Set containers' Security Context runAsUser + ## @param disasterRecovery.cronjob.containerSecurityContext.runAsGroup Set containers' Security Context runAsGroup + ## @param disasterRecovery.cronjob.containerSecurityContext.runAsNonRoot Set container's Security Context runAsNonRoot + ## @param disasterRecovery.cronjob.containerSecurityContext.privileged Set container's Security Context privileged + ## @param disasterRecovery.cronjob.containerSecurityContext.readOnlyRootFilesystem Set container's Security Context readOnlyRootFilesystem + ## @param disasterRecovery.cronjob.containerSecurityContext.allowPrivilegeEscalation Set container's Security Context allowPrivilegeEscalation + ## @param disasterRecovery.cronjob.containerSecurityContext.capabilities.drop List of capabilities to be dropped + ## @param disasterRecovery.cronjob.containerSecurityContext.seccompProfile.type Set container's Security Context seccomp profile + ## + containerSecurityContext: + enabled: true + seLinuxOptions: {} + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + privileged: false + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" + ## Configure resource requests and limits for snapshotter containers + ## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## We usually recommend not to specify default resources and to leave this as a conscious + ## choice for the user. This also increases chances charts run on environments with little + ## resources, such as Minikube. If you do want to specify resources, uncomment the following + ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. + ## @param disasterRecovery.cronjob.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if disasterRecovery.cronjob.resources is set (disasterRecovery.cronjob.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "nano" + ## @param disasterRecovery.cronjob.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## + resources: {} + ## @param disasterRecovery.cronjob.nodeSelector Node labels for cronjob pods assignment + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + ## + nodeSelector: {} + ## @param disasterRecovery.cronjob.tolerations Tolerations for cronjob pods assignment + ## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param disasterRecovery.cronjob.podLabels [object] Labels that will be added to pods created by cronjob + ## + podLabels: {} + ## @param disasterRecovery.cronjob.serviceAccountName Specifies the service account to use for disaster recovery cronjob + ## + serviceAccountName: "" + ## @param disasterRecovery.cronjob.command Override default snapshot container command (useful when you want to customize the snapshot logic) + ## + command: [] + ## + pvc: + ## @param disasterRecovery.pvc.existingClaim A manually managed Persistent Volume and Claim + ## If defined, PVC must be created manually before volume will be bound + ## The value is evaluated as a template, so, for example, the name can depend on .Release or .Chart + ## + existingClaim: "" + ## @param disasterRecovery.pvc.size PVC Storage Request + ## + size: 2Gi + ## @param disasterRecovery.pvc.storageClassName Storage Class for snapshots volume + ## + storageClassName: nfs + ## @param disasterRecovery.pvc.subPath Path within the volume from which to mount + ## Useful if snapshots should only be stored in a subdirectory of the volume + ## + subPath: "" +## @section Service account parameters +## +serviceAccount: + ## @param serviceAccount.create Enable/disable service account creation + ## + create: true + ## @param serviceAccount.name Name of the service account to create or use + ## + name: "" + ## @param serviceAccount.automountServiceAccountToken Enable/disable auto mounting of service account token + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server + ## + automountServiceAccountToken: false + ## @param serviceAccount.annotations [object] Additional annotations to be included on the service account + ## + annotations: {} + ## @param serviceAccount.labels [object] Additional labels to be included on the service account + ## + labels: {} + +## @section etcd "pre-upgrade" K8s Job parameters +## +preUpgradeJob: + ## @param preUpgradeJob.enabled Enable running a pre-upgrade job on Helm upgrades that removes obsolete members + ## + enabled: true + ## @param preUpgradeJob.annotations [object] Add annotations to the etcd "pre-upgrade" job + ## + annotations: {} + ## @param preUpgradeJob.podLabels Additional pod labels for etcd "pre-upgrade" job + ## Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + ## + podLabels: {} + ## @param preUpgradeJob.podAnnotations Additional pod annotations for etcd "pre-upgrade" job + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## @param preUpgradeJob.podAffinityPreset Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param preUpgradeJob.podAntiAffinityPreset Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## Node affinity preset + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## @param preUpgradeJob.nodeAffinityPreset.type Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` + ## @param preUpgradeJob.nodeAffinityPreset.key Node label key to match. Ignored if `affinity` is set. + ## @param preUpgradeJob.nodeAffinityPreset.values [array] Node label values to match. Ignored if `affinity` is set. + ## + nodeAffinityPreset: + type: "" + ## e.g: + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## e.g: + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param preUpgradeJob.affinity [object] Affinity for pod assignment + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set + ## + affinity: {} + ## @param preUpgradeJob.nodeSelector [object] Node labels for pod assignment + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + ## + nodeSelector: {} + ## @param preUpgradeJob.tolerations [array] Tolerations for pod assignment + ## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## Configure "pre-upgrade" job's container Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + ## @param preUpgradeJob.containerSecurityContext.enabled Enabled "pre-upgrade" job's containers' Security Context + ## @param preUpgradeJob.containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in "pre-upgrade" job's containers + ## @param preUpgradeJob.containerSecurityContext.runAsUser Set runAsUser in "pre-upgrade" job's containers' Security Context + ## @param preUpgradeJob.containerSecurityContext.runAsGroup Set runAsUser in "pre-upgrade" job's containers' Security Context + ## @param preUpgradeJob.containerSecurityContext.runAsNonRoot Set runAsNonRoot in "pre-upgrade" job's containers' Security Context + ## @param preUpgradeJob.containerSecurityContext.readOnlyRootFilesystem Set readOnlyRootFilesystem in "pre-upgrade" job's containers' Security Context + ## @param preUpgradeJob.containerSecurityContext.privileged Set privileged in "pre-upgrade" job's containers' Security Context + ## @param preUpgradeJob.containerSecurityContext.allowPrivilegeEscalation Set allowPrivilegeEscalation in "pre-upgrade" job's containers' Security Context + ## @param preUpgradeJob.containerSecurityContext.capabilities.add List of capabilities to be added in "pre-upgrade" job's containers + ## @param preUpgradeJob.containerSecurityContext.capabilities.drop List of capabilities to be dropped in "pre-upgrade" job's containers + ## @param preUpgradeJob.containerSecurityContext.seccompProfile.type Set seccomp profile in "pre-upgrade" job's containers + ## + containerSecurityContext: + enabled: true + seLinuxOptions: {} + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + readOnlyRootFilesystem: true + privileged: false + allowPrivilegeEscalation: false + capabilities: + add: [] + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" + ## Configure "pre-upgrade" job's pod Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param preUpgradeJob.podSecurityContext.enabled Enabled "pre-upgrade" job's pods' Security Context + ## @param preUpgradeJob.podSecurityContext.fsGroupChangePolicy Set fsGroupChangePolicy in "pre-upgrade" job's pods' Security Context + ## @param preUpgradeJob.podSecurityContext.sysctls List of sysctls to allow in "pre-upgrade" job's pods' Security Context + ## @param preUpgradeJob.podSecurityContext.supplementalGroups List of supplemental groups to add to "pre-upgrade" job's pods' Security Context + ## @param preUpgradeJob.podSecurityContext.fsGroup Set fsGroup in "pre-upgrade" job's pods' Security Context + ## + podSecurityContext: + enabled: true + fsGroupChangePolicy: Always + sysctls: [] + supplementalGroups: [] + fsGroup: 1001 + ## etcd "pre-upgrade" job's container resource requests and limits + ## ref: http://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## @param preUpgradeJob.resourcesPreset Set etcd "pre-upgrade" job's container resources according to one common preset (allowed values: none, nano, small, medium, large, xlarge, 2xlarge). This is ignored if preUpgradeJob.resources is set (preUpgradeJob.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "micro" + ## @param preUpgradeJob.resources Set etcd "pre-upgrade" job's container requests and limits for different resources like CPU or memory (essential for production workloads) + ## E.g: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## + resources: {} + ## etcd "pre-upgrade" job's optional delay + ## @param preUpgradeJob.startDelay Optional delay before starting the pre-upgrade hook (in seconds). + startDelay: "" + +## @section Defragmentation parameters +## + +## Enable defragmentation by periodically rearranging fragmented data after history compaction. +## It creates a cronjob to periodically run the defragmentation command: +## etcdctl defrag [OPTIONS] +## See https://etcd.io/docs/latest/op-guide/maintenance/ +## +defrag: + ## @param defrag.enabled Enable automatic defragmentation. This is most effective when paired with auto compaction: consider setting "autoCompactionRetention > 0". + ## + enabled: false + cronjob: + ## @param defrag.cronjob.startingDeadlineSeconds Number of seconds representing the deadline for starting the job if it misses scheduled time for any reason + ## + startingDeadlineSeconds: "" + ## @param defrag.cronjob.schedule Schedule in Cron format to defrag (daily at midnight by default) + ## See https://en.wikipedia.org/wiki/Cron + ## + schedule: "0 0 * * *" + ## @param defrag.cronjob.concurrencyPolicy Set the cronjob parameter concurrencyPolicy + ## + concurrencyPolicy: Forbid + ## @param defrag.cronjob.suspend Boolean that indicates if the controller must suspend subsequent executions (not applied to already started executions) + ## + suspend: false + ## @param defrag.cronjob.successfulJobsHistoryLimit Number of successful finished jobs to retain + ## + successfulJobsHistoryLimit: 1 + ## @param defrag.cronjob.failedJobsHistoryLimit Number of failed finished jobs to retain + ## + failedJobsHistoryLimit: 1 + ## @param defrag.cronjob.labels [object] Additional labels to be added to the Defrag cronjob + ## + labels: {} + ## @param defrag.cronjob.annotations [object] Annotations to be added to the Defrag cronjob + ## + annotations: {} + ## @param defrag.cronjob.activeDeadlineSeconds Number of seconds relative to the startTime that the job may be continuously active before the system tries to terminate it + ## + activeDeadlineSeconds: "" + ## @param defrag.cronjob.restartPolicy Set the cronjob parameter restartPolicy + ## + restartPolicy: OnFailure + ## @param defrag.cronjob.podLabels [object] Labels that will be added to pods created by Defrag cronjob + ## + podLabels: {} + ## @param defrag.cronjob.podAnnotations [object] Pod annotations for Defrag cronjob pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## K8s Security Context for Defrag cronjob pods + ## https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## @param defrag.cronjob.podSecurityContext.enabled Enable security context for Defrag pods + ## @param defrag.cronjob.podSecurityContext.fsGroupChangePolicy Set filesystem group change policy + ## @param defrag.cronjob.podSecurityContext.sysctls Set kernel settings using the sysctl interface + ## @param defrag.cronjob.podSecurityContext.supplementalGroups Set filesystem extra groups + ## @param defrag.cronjob.podSecurityContext.fsGroup Group ID for the Defrag filesystem + ## + podSecurityContext: + enabled: true + fsGroupChangePolicy: Always + sysctls: [] + supplementalGroups: [] + fsGroup: 1001 + ## Configure container security context for Defrag cronjob containers + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param defrag.cronjob.containerSecurityContext.enabled Enabled containers' Security Context + ## @param defrag.cronjob.containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in container + ## @param defrag.cronjob.containerSecurityContext.runAsUser Set containers' Security Context runAsUser + ## @param defrag.cronjob.containerSecurityContext.runAsGroup Set containers' Security Context runAsGroup + ## @param defrag.cronjob.containerSecurityContext.runAsNonRoot Set container's Security Context runAsNonRoot + ## @param defrag.cronjob.containerSecurityContext.privileged Set container's Security Context privileged + ## @param defrag.cronjob.containerSecurityContext.readOnlyRootFilesystem Set container's Security Context readOnlyRootFilesystem + ## @param defrag.cronjob.containerSecurityContext.allowPrivilegeEscalation Set container's Security Context allowPrivilegeEscalation + ## @param defrag.cronjob.containerSecurityContext.capabilities.drop List of capabilities to be dropped + ## @param defrag.cronjob.containerSecurityContext.seccompProfile.type Set container's Security Context seccomp profile + ## + containerSecurityContext: + enabled: true + seLinuxOptions: {} + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + privileged: false + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" + ## @param defrag.cronjob.nodeSelector [object] Node labels for pod assignment in Defrag cronjob + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + ## + nodeSelector: {} + ## @param defrag.cronjob.tolerations [array] Tolerations for pod assignment in Defrag cronjob + ## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param defrag.cronjob.serviceAccountName Specifies the service account to use for Defrag cronjob + ## + serviceAccountName: "" + ## @param defrag.cronjob.command [array] Override default container command for defragmentation (useful when using custom images) + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + command: [] + ## @param defrag.cronjob.args [array] Override default container args (useful when using custom images) + ## + args: [] + ## @param defrag.cronjob.resourcesPreset Set container resources according to one common preset + ## (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if + ## defrag.cronjob.resources is set (defrag.cronjob.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "nano" + ## @param defrag.cronjob.resources [object] Set container requests and limits for different resources like CPU or + ## memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## + resources: {} + ## @param defrag.cronjob.extraEnvVars [array] Extra environment variables to be set on defrag cronjob container + ## e.g: + ## extraEnvVars: + ## - name: FOO + ## value: "bar" + ## + extraEnvVars: [] + ## @param defrag.cronjob.extraEnvVarsCM Name of existing ConfigMap containing extra env vars + ## + extraEnvVarsCM: "" + ## @param defrag.cronjob.extraEnvVarsSecret Name of existing Secret containing extra env vars + ## + extraEnvVarsSecret: "" + +## @section Other parameters +## + +## etcd Pod Disruption Budget configuration +## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ +## +pdb: + ## @param pdb.create Enable/disable a Pod Disruption Budget creation + ## + create: true + ## @param pdb.minAvailable Minimum number/percentage of pods that should remain scheduled + ## + minAvailable: 51% + ## @param pdb.maxUnavailable Maximum number/percentage of pods that may be made unavailable + ## + maxUnavailable: "" diff --git a/charts/mayastor/charts/jaeger-operator/.helmignore b/charts/mayastor/charts/jaeger-operator/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/charts/mayastor/charts/jaeger-operator/COMPATIBILITY.md b/charts/mayastor/charts/jaeger-operator/COMPATIBILITY.md new file mode 100644 index 0000000..95218d8 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/COMPATIBILITY.md @@ -0,0 +1,35 @@ +The following table shows the compatibility of `Jaeger Operator helm chart` with different components, in this particular case we shows Jaeger Operator, Kubernetes and Strimzi operator compatibility. Cert-manager installed or certificate for webhook service in a secret is required in version 2.29.0+ of the helm chart. + +| Chart version | Jaeger Operator | Kubernetes | Strimzi Operator | Cert-Manager | +|---------------------------|-----------------|-----------------|--------------------|--------------| +| 2.50.0 | v1.52.x | v1.19 to v1.28 | v0.32 | v1.6.1+ | +| 2.49.0 | v1.49.x | v1.19 to v1.28 | v0.32 | v1.6.1+ | +| 2.47.0 | v1.47.x | v1.19 to v1.26 | v0.23 | v1.6.1+ | +| 2.46.0 | v1.46.x | v1.19 to v1.26 | v0.23 | v1.6.1+ | +| 2.45.0 | v1.45.x | v1.19 to v1.26 | v0.23 | v1.6.1+ | +| 2.42.0 | v1.43.x | v1.19 to v1.26 | v0.23 | v1.6.1+ | +| 2.41.0 | v1.42.x | v1.19 to v1.24 | v0.23 | v1.6.1+ | +| (Missing) | | v1.19 to v1.23 | v0.23 | v1.6.1+ | +| (Missing) | v1.41.x | v1.19 to v1.23 | v0.23 | v1.6.1+ | +| (Missing) | v1.40.x | v1.19 to v1.23 | v0.23 | v1.6.1+ | +| 2.37.0 | v1.39.x | v1.19 to v1.24 | v0.23 | v1.6.1+ | +| 2.36.0 | v1.38.x | v1.19 to v1.24 | v0.23 | v1.6.1+ | +| 2.35.0 | v1.37.x | v1.19 to v1.24 | v0.23 | v1.6.1+ | +| 2.34.0 | v1.36.x | v1.19 to v1.24 | v0.23 | v1.6.1+ | +| 2.33.0 | v1.35.x | v1.19 to v1.24 | v0.23 | v1.6.1+ | +| 2.32.0(C), 2.32.1, 2.32.2 | v1.34.x | v1.19 to v1.24 | v0.23 | v1.6.1+ | +| (Missing) | v1.33.x | v1.19 to v1.23 | v0.23 | v1.6.1+ | +| 2.30.0(C), 2.31.0(C) | v1.32.x | v1.19 to v1.21 | v0.23 | v1.6.1+ | +| 2.29.0(C) | v1.31.x | v1.19 to v1.21 | v0.23 | v1.6.1+ | +| 2.28.0 | v1.30.x | v1.19 to v1.21 | v0.23 | | +| 2.27.1 | v1.29.x | v1.19 to v1.21 | v0.23 | | +| 2.27.0 | v1.28.x | v1.19 to v1.21 | v0.23 | | +| 2.26.0 | v1.27.x | v1.19 to v1.21 | v0.23 | | +| (Missing) | v1.26.x | v1.19 to v1.21 | v0.23 | | +| (Missing) | v1.25.x | v1.19 to v1.21 | v0.23 | | +| 2.23.0, 2.24.0, 2.25.0 | v1.24.x | v1.19 to v1.21 | v0.23 | | +| (Missing) | v1.23.x | v1.19 to v1.21 | v0.19, v0.20 | | +| 2.21.* | v1.22.x | v1.18 to v1.20 | v0.19 | | +Legend: +- `(C)` Chart is corrupted. Please do not use it, see [link](https://github.com/jaegertracing/helm-charts/issues/351) and [link](https://github.com/jaegertracing/helm-charts/issues/373) +- `(Missing)` Missing chart version for specified Jaeger Operator version \ No newline at end of file diff --git a/charts/mayastor/charts/jaeger-operator/Chart.yaml b/charts/mayastor/charts/jaeger-operator/Chart.yaml new file mode 100644 index 0000000..c2eaccb --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/Chart.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +appVersion: 1.52.0 +description: jaeger-operator Helm chart for Kubernetes +home: https://www.jaegertracing.io/ +icon: https://www.jaegertracing.io/img/jaeger-icon-reverse-color.svg +maintainers: +- email: ctadeu@gmail.com + name: cpanato +- email: batazor111@gmail.com + name: batazor +name: jaeger-operator +sources: +- https://github.com/jaegertracing/jaeger-operator +version: 2.50.1 diff --git a/charts/mayastor/charts/jaeger-operator/README.md b/charts/mayastor/charts/jaeger-operator/README.md new file mode 100644 index 0000000..ffac4e3 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/README.md @@ -0,0 +1,142 @@ +# jaeger-operator + +[jaeger-operator](https://github.com/jaegertracing/jaeger-operator) is a Kubernetes operator. + +## Install + +```console +$ helm install jaegertracing/jaeger-operator +``` + +## Introduction + +This chart bootstraps a jaeger-operator deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3 +- cert-manager 1.6.1+ installed, or certificate for webhook service in a secret + +## Check compability matrix + +See the compatibility matrix [here](./COMPATIBILITY.md). + +## Installing the Chart + +Add the Jaeger Tracing Helm repository: + +```console +$ helm repo add jaegertracing https://jaegertracing.github.io/helm-charts +``` + +To install the chart with the release name `my-release` in `observability` namespace: + +```console +$ helm install my-release jaegertracing/jaeger-operator -n observability +``` + +The command deploys jaeger-operator on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Configuration + +The following table lists the configurable parameters of the jaeger-operator chart and their default values. + +| Parameter | Description | Default | +| :------------------------- | :---------------------------------------------------------------------------------------------------------- |:--------------------------------| +| `serviceExtraLabels` | Additional labels to jaeger-operator service | `{}` | +| `extraLabels` | Additional labels to jaeger-operator deployment | `{}` | +| `image.repository` | Controller container image repository | `jaegertracing/jaeger-operator` | +| `image.tag` | Controller container image tag | `1.52.0` | +| `image.pullPolicy` | Controller container image pull policy | `IfNotPresent` | +| `jaeger.create` | Jaeger instance will be created | `false` | +| `jaeger.spec` | Jaeger instance specification | `{}` | +| `rbac.create` | All required roles and rolebindings will be created | `true` | +| `serviceAccount.create` | Service account to use | `true` | +| `rbac.pspEnabled` | Pod security policy for pod will be created and included in rbac role | `false` | +| `rbac.clusterRole` | ClusterRole will be used by operator ServiceAccount | `false` | +| `serviceAccount.name` | Service account name to use. If not set and create is true, a name is generated using the fullname template | `nil` | +| `extraEnv` | Additional environment variables passed to the operator. For example: name: LOG-LEVEL value: debug | `[]` | +| `resources` | K8s pod resources | `None` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `tolerations` | Toleration labels for pod assignment | `[]` | +| `affinity` | Affinity settings for pod assignment | `{}` | +| `securityContext` | Security context for pod | `{}` | +| `containerSecurityContext` | Security context for the container | `{}` | +| `priorityClassName` | Priority class name for the pod | `None` | + +Specify each parameter you'd like to override using a YAML file as described above in the [installation](#installing-the-chart) section. + +You can also specify any non-array parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +$ helm install jaegertracing/jaeger-operator --name my-release \ + --set rbac.create=false +``` + +To install the chart without creating the CRDs (any files under `chart/crds`) make use of the `--skip-crds` flag. For example, + +```console +$ helm install jaegertracing/jaeger-operator --name my-release \ + --skip-crds +``` + +## After the Helm Installation + +### Creating a new Jaeger instance + +The simplest possible way to install is by creating a YAML file like the following: + +```YAML +apiVersion: jaegertracing.io/v1 +kind: Jaeger +metadata: + name: simplest +``` + +The YAML file can then be used with `kubectl`: + +```console +$ kubectl apply -f simplest.yaml +``` + +### Creating a new Jaeger with ElasticSearch + +To do that you need to have an ElasticSearch installed in your Kubernetes cluster or install one using the [Helm Chart](https://github.com/helm/charts/tree/master/incubator/elasticsearch) available for that. + +After that just deploy the following manifest: + +```YAML +# setup an elasticsearch with `make es` +apiVersion: jaegertracing.io/v1 +kind: Jaeger +metadata: + name: simple-prod +spec: + strategy: production + storage: + type: elasticsearch + options: + es: + server-urls: http://elasticsearch:9200 + username: elastic + password: changeme +``` + +The YAML file can then be used with `kubectl`: + +```console +$ kubectl apply -f simple-prod.yaml +``` diff --git a/charts/mayastor/charts/jaeger-operator/crds/crd.yaml b/charts/mayastor/charts/jaeger-operator/crds/crd.yaml new file mode 100644 index 0000000..bb430b2 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/crds/crd.yaml @@ -0,0 +1,14866 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: jaegers.jaegertracing.io + labels: + app.kubernetes.io/name: jaeger-operator + app.kubernetes.io/instance: jaeger-operator +spec: + group: jaegertracing.io + names: + kind: Jaeger + listKind: JaegerList + plural: jaegers + singular: jaeger + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Jaeger instance's status + jsonPath: .status.phase + name: Status + type: string + - description: Jaeger Version + jsonPath: .status.version + name: Version + type: string + - description: Jaeger deployment strategy + jsonPath: .spec.strategy + name: Strategy + type: string + - description: Jaeger storage type + jsonPath: .spec.storage.type + name: Storage + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + agent: + nullable: true + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + nullable: true + type: object + config: + type: object + x-kubernetes-preserve-unknown-fields: true + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + dnsPolicy: + type: string + hostNetwork: + type: boolean + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + labels: + additionalProperties: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + options: + type: object + x-kubernetes-preserve-unknown-fields: true + priorityClassName: + type: string + resources: + nullable: true + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + sidecarSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + strategy: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object + allInOne: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + nullable: true + type: object + config: + type: object + x-kubernetes-preserve-unknown-fields: true + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + labels: + additionalProperties: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + metricsStorage: + properties: + type: + type: string + type: object + options: + type: object + x-kubernetes-preserve-unknown-fields: true + priorityClassName: + type: string + resources: + nullable: true + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + tracingEnabled: + type: boolean + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object + annotations: + additionalProperties: + type: string + nullable: true + type: object + collector: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + nullable: true + type: object + autoscale: + type: boolean + config: + type: object + x-kubernetes-preserve-unknown-fields: true + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + kafkaSecretName: + type: string + labels: + additionalProperties: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + nodeSelector: + additionalProperties: + type: string + nullable: true + type: object + options: + type: object + x-kubernetes-preserve-unknown-fields: true + priorityClassName: + type: string + replicas: + format: int32 + type: integer + resources: + nullable: true + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceType: + type: string + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + ingester: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + nullable: true + type: object + autoscale: + type: boolean + config: + type: object + x-kubernetes-preserve-unknown-fields: true + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + kafkaSecretName: + type: string + labels: + additionalProperties: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + nodeSelector: + additionalProperties: + type: string + nullable: true + type: object + options: + type: object + x-kubernetes-preserve-unknown-fields: true + replicas: + format: int32 + type: integer + resources: + nullable: true + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object + ingress: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + nullable: true + type: object + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + enabled: + type: boolean + hosts: + items: + type: string + type: array + x-kubernetes-list-type: atomic + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + ingressClassName: + type: string + labels: + additionalProperties: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + openshift: + properties: + delegateUrls: + type: string + htpasswdFile: + type: string + sar: + type: string + skipLogout: + type: boolean + type: object + options: + type: object + x-kubernetes-preserve-unknown-fields: true + pathType: + type: string + resources: + nullable: true + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + secretName: + type: string + security: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + tls: + items: + properties: + hosts: + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object + labels: + additionalProperties: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + query: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + nullable: true + type: object + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + grpcNodePort: + format: int32 + type: integer + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + labels: + additionalProperties: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + metricsStorage: + properties: + type: + type: string + type: object + nodePort: + format: int32 + type: integer + nodeSelector: + additionalProperties: + type: string + nullable: true + type: object + options: + type: object + x-kubernetes-preserve-unknown-fields: true + priorityClassName: + type: string + replicas: + format: int32 + type: integer + resources: + nullable: true + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceType: + type: string + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + tracingEnabled: + type: boolean + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object + resources: + nullable: true + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + sampling: + properties: + options: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + storage: + properties: + cassandraCreateSchema: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + datacenter: + type: string + enabled: + type: boolean + image: + type: string + mode: + type: string + timeout: + type: string + traceTTL: + type: string + ttlSecondsAfterFinished: + format: int32 + type: integer + type: object + dependencies: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + nullable: true + type: object + backoffLimit: + format: int32 + type: integer + cassandraClientAuthEnabled: + type: boolean + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + elasticsearchClientNodeOnly: + type: boolean + elasticsearchNodesWanOnly: + type: boolean + elasticsearchTimeRange: + type: string + enabled: + type: boolean + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + javaOpts: + type: string + labels: + additionalProperties: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + nullable: true + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + schedule: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + sparkMaster: + type: string + successfulJobsHistoryLimit: + format: int32 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + ttlSecondsAfterFinished: + format: int32 + type: integer + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object + elasticsearch: + properties: + doNotProvision: + type: boolean + image: + type: string + name: + type: string + nodeCount: + format: int32 + type: integer + nodeSelector: + additionalProperties: + type: string + type: object + proxyResources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + redundancyPolicy: + enum: + - FullRedundancy + - MultipleRedundancy + - SingleRedundancy + - ZeroRedundancy + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + storage: + properties: + size: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + storageClassName: + type: string + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + useCertManagement: + type: boolean + type: object + esIndexCleaner: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + nullable: true + type: object + backoffLimit: + format: int32 + type: integer + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + enabled: + type: boolean + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + labels: + additionalProperties: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + numberOfDays: + type: integer + priorityClassName: + type: string + resources: + nullable: true + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + schedule: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + successfulJobsHistoryLimit: + format: int32 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + ttlSecondsAfterFinished: + format: int32 + type: integer + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object + esRollover: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + nullable: true + type: object + backoffLimit: + format: int32 + type: integer + conditions: + type: string + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + labels: + additionalProperties: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + readTTL: + type: string + resources: + nullable: true + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + schedule: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + successfulJobsHistoryLimit: + format: int32 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + ttlSecondsAfterFinished: + format: int32 + type: integer + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object + grpcPlugin: + properties: + image: + type: string + type: object + options: + type: object + x-kubernetes-preserve-unknown-fields: true + secretName: + type: string + type: + type: string + type: object + strategy: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + ui: + properties: + options: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object + status: + properties: + phase: + type: string + version: + type: string + required: + - phase + - version + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/mayastor/charts/jaeger-operator/templates/NOTES.txt b/charts/mayastor/charts/jaeger-operator/templates/NOTES.txt new file mode 100644 index 0000000..23c62a9 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/NOTES.txt @@ -0,0 +1,8 @@ +jaeger-operator is installed. + + +Check the jaeger-operator logs + export POD=$(kubectl get pods -l app.kubernetes.io/instance={{ .Release.Name }} -l app.kubernetes.io/name=jaeger-operator --namespace {{ .Release.Namespace }} --output name) + kubectl logs $POD --namespace={{ .Release.Namespace }} + + diff --git a/charts/mayastor/charts/jaeger-operator/templates/_helpers.tpl b/charts/mayastor/charts/jaeger-operator/templates/_helpers.tpl new file mode 100644 index 0000000..ec2de02 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/_helpers.tpl @@ -0,0 +1,49 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "jaeger-operator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +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 "jaeger-operator.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "jaeger-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "jaeger-operator.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "jaeger-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* Generate basic labels */}} +{{- define "jaeger-operator.labels" }} +app.kubernetes.io/name: {{ include "jaeger-operator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/mayastor/charts/jaeger-operator/templates/certificate.yaml b/charts/mayastor/charts/jaeger-operator/templates/certificate.yaml new file mode 100644 index 0000000..67871f2 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/certificate.yaml @@ -0,0 +1,22 @@ +{{- if .Values.certs.certificate.create }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ default "jaeger-operator-service-cert" .Values.certs.certificate.secretName }} + namespace: {{ .Release.Namespace }} +spec: + dnsNames: + - "{{ default "jaeger-operator-webhook-service" .Values.webhooks.service.name }}.{{ .Release.Namespace }}.svc" + - "{{ default "jaeger-operator-webhook-service" .Values.webhooks.service.name }}.{{ .Release.Namespace }}.svc.cluster.local" + issuerRef: + {{- if .Values.certs.issuer.create }} + kind: Issuer + {{- else }} + kind: {{ .Values.certs.certificate.issuerKind }} + {{- end }} + name: {{ default "selfsigned-issuer" .Values.certs.issuer.name }} + secretName: {{ default "jaeger-operator-service-cert" .Values.certs.certificate.secretName }} + subject: + organizationalUnits: + - "{{ include "jaeger-operator.name" . }}" +{{- end }} diff --git a/charts/mayastor/charts/jaeger-operator/templates/deployment.yaml b/charts/mayastor/charts/jaeger-operator/templates/deployment.yaml new file mode 100644 index 0000000..3186217 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/deployment.yaml @@ -0,0 +1,106 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "jaeger-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} +{{- with .Values.extraLabels }} +{{ . | toYaml | indent 4 }} +{{- end }} +spec: + replicas: 1 + selector: + matchLabels: +{{ include "jaeger-operator.labels" . | indent 6 }} + template: + metadata: + name: {{ include "jaeger-operator.fullname" . }} + labels: +{{ include "jaeger-operator.labels" . | indent 8 }} +{{- with .Values.extraLabels }} +{{ . | toYaml | indent 8 }} +{{- end }} + spec: + {{- if .Values.serviceAccount.create }} + serviceAccountName: {{ include "jaeger-operator.serviceAccountName" . }} + {{- end }} + {{- with .Values.securityContext }} + securityContext: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + {{- if and .Values.image.imagePullSecrets (not .Values.serviceAccount.create ) }} + imagePullSecrets: + {{- range .Values.image.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + {{- if .Values.hostNetwork }} + hostNetwork: {{ .Values.hostNetwork }} + {{- end }} + containers: + - name: {{ include "jaeger-operator.fullname" . }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.metricsPort }} + name: metrics + - containerPort: {{ .Values.webhooks.port }} + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + args: + - start + - {{ printf "--metrics-port=%v" .Values.metricsPort }} + - {{ printf "--webhook-bind-port=%v" .Values.webhooks.port }} + env: + - name: WATCH_NAMESPACE + {{- if .Values.rbac.clusterRole }} + value: "" + {{- else }} + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: OPERATOR_NAME + value: {{ include "jaeger-operator.fullname" . | quote }} + {{- if .Values.extraEnv }} + {{- toYaml .Values.extraEnv | nindent 12 }} + {{- end }} + resources: +{{ toYaml .Values.resources | indent 12 }} + {{- with .Values.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: {{ default "jaeger-operator-service-cert" .Values.certs.certificate.secretName }} + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} diff --git a/charts/mayastor/charts/jaeger-operator/templates/issuer.yaml b/charts/mayastor/charts/jaeger-operator/templates/issuer.yaml new file mode 100644 index 0000000..19b2382 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/issuer.yaml @@ -0,0 +1,9 @@ +{{- if .Values.certs.issuer.create }} +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ default "selfsigned-issuer" .Values.certs.issuer.name }} + namespace: {{ .Release.Namespace }} +spec: + selfSigned: {} +{{- end }} diff --git a/charts/mayastor/charts/jaeger-operator/templates/jaeger.yaml b/charts/mayastor/charts/jaeger-operator/templates/jaeger.yaml new file mode 100644 index 0000000..0c4f9d2 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/jaeger.yaml @@ -0,0 +1,11 @@ +{{- if .Values.jaeger.create }} +apiVersion: jaegertracing.io/v1 +kind: Jaeger +metadata: + name: {{ include "jaeger-operator.fullname" . }}-jaeger + namespace: {{ default .Release.Namespace .Values.jaeger.namespace }} +{{- with .Values.jaeger.spec }} +spec: +{{ toYaml . | indent 2}} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/jaeger-operator/templates/mutating-webhook.yaml b/charts/mayastor/charts/jaeger-operator/templates/mutating-webhook.yaml new file mode 100644 index 0000000..9ae6462 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/mutating-webhook.yaml @@ -0,0 +1,57 @@ +{{- if and (.Values.webhooks.mutatingWebhook.create) (.Values.webhooks.service.create) }} +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: {{ default .Release.Namespace .Values.certs.certificate.namespace }}/{{ default "jaeger-operator-service-cert" .Values.certs.certificate.secretName }} + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} + name: jaeger-operator-mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ default "jaeger-operator-webhook-service" .Values.webhooks.service.name }} + namespace: {{ .Release.Namespace }} + path: /mutate-v1-deployment + failurePolicy: Ignore + name: deployment.sidecar-injector.jaegertracing.io + objectSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: NotIn + values: + - {{ include "jaeger-operator.name" . }} + rules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - deployments + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ default "jaeger-operator-webhook-service" .Values.webhooks.service.name }} + namespace: {{ .Release.Namespace }} + path: /mutate-jaegertracing-io-v1-jaeger + failurePolicy: Fail + name: mjaeger.kb.io + rules: + - apiGroups: + - jaegertracing.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - jaegers + sideEffects: None +{{- end }} diff --git a/charts/mayastor/charts/jaeger-operator/templates/psp.yaml b/charts/mayastor/charts/jaeger-operator/templates/psp.yaml new file mode 100644 index 0000000..7d7cca5 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/psp.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "jaeger-operator.fullname" . }}-operator-psp + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} +spec: + privileged: false + allowPrivilegeEscalation: false + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAsNonRoot' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/charts/mayastor/charts/jaeger-operator/templates/role-binding.yaml b/charts/mayastor/charts/jaeger-operator/templates/role-binding.yaml new file mode 100644 index 0000000..533f828 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/role-binding.yaml @@ -0,0 +1,17 @@ +{{- if .Values.rbac.create }} +kind: {{ if .Values.rbac.clusterRole }}Cluster{{ end }}RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "jaeger-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} +subjects: +- kind: ServiceAccount + namespace: {{ .Release.Namespace }} + name: {{ include "jaeger-operator.serviceAccountName" . }} +roleRef: + kind: {{ if .Values.rbac.clusterRole }}Cluster{{ end }}Role + name: {{ include "jaeger-operator.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/charts/mayastor/charts/jaeger-operator/templates/role.yaml b/charts/mayastor/charts/jaeger-operator/templates/role.yaml new file mode 100644 index 0000000..ccc308d --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/role.yaml @@ -0,0 +1,267 @@ +{{- if .Values.rbac.create }} +kind: {{ if .Values.rbac.clusterRole }}Cluster{{ end }}Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "jaeger-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} +rules: +- apiGroups: + - apps + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - deployments/status + verbs: + - get + - patch + - update +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - batch + resources: + - cronjobs + - jobs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - console.openshift.io + resources: + - consolelinks + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - list + - update +- apiGroups: + - "" + resources: + - configmaps + - persistentvolumeclaims + - pods + - secrets + - serviceaccounts + - services + - services/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - namespaces/status + verbs: + - get + - patch + - update +- apiGroups: + - extensions + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - image.openshift.io + resources: + - imagestreams + verbs: + - get + - list + - watch +- apiGroups: + - jaegertracing.io + resources: + - jaegers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - jaegertracing.io + resources: + - jaegers/finalizers + verbs: + - update +- apiGroups: + - jaegertracing.io + resources: + - jaegers/status + verbs: + - get + - patch + - update +- apiGroups: + - kafka.strimzi.io + resources: + - kafkas + - kafkausers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - logging.openshift.io + resources: + - elasticsearch + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - logging.openshift.io + resources: + - elasticsearches + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +{{- if .Values.rbac.pspEnabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ include "jaeger-operator.fullname" . }}-operator-psp +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/jaeger-operator/templates/service-account.yaml b/charts/mayastor/charts/jaeger-operator/templates/service-account.yaml new file mode 100644 index 0000000..dc8eea6 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/service-account.yaml @@ -0,0 +1,19 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "jaeger-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} +{{- if .Values.serviceAccount.annotations }} + annotations: +{{ toYaml .Values.serviceAccount.annotations | indent 4 }} +{{- end }} +{{- if .Values.image.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.image.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/jaeger-operator/templates/service.yaml b/charts/mayastor/charts/jaeger-operator/templates/service.yaml new file mode 100644 index 0000000..46705f8 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/service.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "jaeger-operator.fullname" . }}-metrics + namespace: {{ .Release.Namespace }} + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} +{{- with .Values.serviceExtraLabels }} +{{ . | toYaml | indent 4 }} +{{- end }} +{{- if .Values.service.annotations }} + annotations: +{{ toYaml .Values.service.annotations | indent 4 }} +{{- end }} +spec: + ports: + - name: metrics + port: {{ .Values.metricsPort }} + protocol: TCP + targetPort: {{ .Values.metricsPort }} +{{- if and (eq .Values.service.type "NodePort") (.Values.service.nodePort) }} + nodePort: {{ .Values.service.nodePort }} +{{- end }} + selector: + app.kubernetes.io/name: {{ include "jaeger-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + type: {{ .Values.service.type }} +--- +{{- if .Values.webhooks.service.create }} +apiVersion: v1 +kind: Service +metadata: + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} + name: {{ default "jaeger-operator-webhook-service" .Values.webhooks.service.name }} + namespace: {{ .Release.Namespace }} +{{- if .Values.webhooks.service.annotations }} + annotations: +{{ toYaml .Values.webhooks.service.annotations | indent 4 }} +{{- end }} +spec: + ports: + - port: 443 + protocol: TCP + targetPort: {{ .Values.webhooks.port }} + selector: +{{ include "jaeger-operator.labels" . | indent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/jaeger-operator/templates/validating-webhook.yaml b/charts/mayastor/charts/jaeger-operator/templates/validating-webhook.yaml new file mode 100644 index 0000000..eb0c318 --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/templates/validating-webhook.yaml @@ -0,0 +1,29 @@ +{{- if and (.Values.webhooks.validatingWebhook.create) (.Values.webhooks.service.create) }} +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: {{ default .Release.Namespace .Values.certs.certificate.namespace }}/{{ default "jaeger-operator-service-cert" .Values.certs.certificate.secretName }} + name: jaeger-operator-validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ default "jaeger-operator-webhook-service" .Values.webhooks.service.name }} + namespace: {{ .Release.Namespace }} + path: /validate-jaegertracing-io-v1-jaeger + failurePolicy: Fail + name: vjaeger.kb.io + rules: + - apiGroups: + - jaegertracing.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - jaegers + sideEffects: None +{{- end }} diff --git a/charts/mayastor/charts/jaeger-operator/values.yaml b/charts/mayastor/charts/jaeger-operator/values.yaml new file mode 100644 index 0000000..77fc3bf --- /dev/null +++ b/charts/mayastor/charts/jaeger-operator/values.yaml @@ -0,0 +1,101 @@ +# Default values for jaeger-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +image: + repository: jaegertracing/jaeger-operator + tag: 1.52.0 + pullPolicy: IfNotPresent + imagePullSecrets: [] + +certs: + issuer: + create: true + name: "" + certificate: + create: true + namespace: "" + secretName: "" + # Specify the cert-manager issuer kind to use an existing cert-manager + # issuer; typically Issuer or ClusterIssuer + # This field will be ignored if issuer.create is true + issuerKind: Issuer + +webhooks: + mutatingWebhook: + create: true + validatingWebhook: + create: true + port: 9443 + service: + annotations: {} + create: true + name: "" + +jaeger: + # Specifies whether Jaeger instance should be created + create: false + # namespace where Jaeger resource should be created default to .Release.Namespace + namespace: + spec: {} + +rbac: + # Specifies whether RBAC resources should be created + create: true + pspEnabled: false + clusterRole: false + +service: + type: ClusterIP + # Specify a specific node port when type is NodePort + # nodePort: 32500 + # Annotations for service + annotations: {} + +serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: + # Annotations for serviceAccount + annotations: {} + +# Specifies extra environment variables passed to the operator: +extraEnv: [] + # Specifies log-level for the operator: + # - name: LOG-LEVEL + # value: debug + +serviceExtraLabels: {} + # Specifies extra labels for the operator-metric service: + # foo: bar + +extraLabels: {} + # Specifies extra labels for the operator deployment: + # foo: bar + +resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +securityContext: {} + +containerSecurityContext: {} + +priorityClassName: + +# Specifies weather host network should be used +hostNetwork: false + +metricsPort: 8383 diff --git a/charts/mayastor/charts/localpv-provisioner/Chart.yaml b/charts/mayastor/charts/localpv-provisioner/Chart.yaml new file mode 100644 index 0000000..bd6066e --- /dev/null +++ b/charts/mayastor/charts/localpv-provisioner/Chart.yaml @@ -0,0 +1,15 @@ +apiVersion: v2 +appVersion: 4.4.0 +description: Helm chart for OpenEBS Dynamic Local PV. For instructions to install + OpenEBS Dynamic Local PV using helm chart, refer to https://openebs.github.io/dynamic-localpv-provisioner/. +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- storage +- local +- dynamic-localpv +name: localpv-provisioner +sources: +- https://github.com/openebs/dynamic-localpv-provisioner +type: application +version: 4.4.0 diff --git a/charts/mayastor/charts/localpv-provisioner/README.md b/charts/mayastor/charts/localpv-provisioner/README.md new file mode 100644 index 0000000..2fb6805 --- /dev/null +++ b/charts/mayastor/charts/localpv-provisioner/README.md @@ -0,0 +1,117 @@ +# OpenEBS LocalPV Provisioner + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Chart Lint and Test](https://github.com/openebs/dynamic-localpv-provisioner/workflows/Chart%20Lint%20and%20Test/badge.svg) +![Release Charts](https://github.com/openebs/dynamic-localpv-provisioner/workflows/Release%20Charts/badge.svg?branch=develop) + +A Helm chart for openebs dynamic localpv provisioner. This chart bootstraps OpenEBS Dynamic LocalPV provisioner deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + + +**Homepage:** + +## Get Repo Info + +```console +helm repo add openebs-localpv https://openebs.github.io/dynamic-localpv-provisioner +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +Please visit the [link](https://openebs.github.io/dynamic-localpv-provisioner/) for install instructions via helm3. + +```console +# Helm +helm install [RELEASE_NAME] openebs-localpv/localpv-provisioner --namespace [NAMESPACE] --create-namespace +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +# Helm +helm uninstall [RELEASE_NAME] --namespace [NAMESPACE] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +# Helm +helm upgrade [RELEASE_NAME] [CHART] --install --namespace [NAMESPACE] +``` + + +## Configuration + +The following table lists the configurable parameters of the OpenEBS Dynamic LocalPV Provisioner chart and their default values. + +You can modify different parameters by specifying the desired value in the `helm install` command by using the `--set` and/or the `--set-string` flag(s). + +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace +``` + +Sample command to install the provisioner with nodeAffinityLabels "openebs.io/node-affinity-key-1" and "openebs.io/node-affinity-key-2" on the hostpath StorageClass: +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace \ + --set-string hostpathClass.nodeAffinityLabels="{openebs.io/node-affinity-key-1,openebs.io/node-affinity-key-2}" +``` + +| Parameter | Description | Default | +| ------------------------------------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------| +| `analytics.enabled` | Enable sending stats to Google Analytics | `true` | +| `analytics.pingInterval` | Duration(hours) between sending ping stat | `24h` | +| `extraLabels` | Additional labels to add to all chart resources | `{}` | +| `global.imageRegistry` | Default image registry, overridden by localpv.image.registry and helperPod.image.registry | `""` | +| `helperPod.image.registry` | Registry for helper image | `""` | +| `helperPod.image.repository` | Image for helper pod | `"openebs/linux-utils"` | +| `helperPod.image.pullPolicy` | Pull policy for helper pod | `"IfNotPresent"` | +| `helperPod.image.tag` | Image tag for helper image | `4.2.0` | +| `hostpathClass.basePath` | BasePath for openebs-hostpath StorageClass | `"/var/openebs/local"` | +| `hostpathClass.enabled` | Enables creation of default Hostpath StorageClass | `true` | +| `hostpathClass.isDefaultClass` | Make openebs-hostpath the default StorageClass | `"false"` | +| `hostpathClass.nodeAffinityLabels` | Custom node label(or labels) key to uniquely identify nodes. `kubernetes.io/hostname` is the default label key for node selection. | `[]` | +| `hostpathClass.xfsQuota.enabled` | Enable XFS Quota (requires XFS filesystem) | `false` | +| `hostpathClass.ext4Quota.enabled` | Enable EXT4 Quota (requires EXT4 filesystem) | `false` | +| `hostpathClass.reclaimPolicy` | ReclaimPolicy for Hostpath PVs | `"Delete"` | +| `imagePullSecrets` | Provides image pull secrect | `""` | +| `localpv.enabled` | Enable LocalPV Provisioner | `true` | +| `localpv.image.registry` | Registry for LocalPV Provisioner image | `""` | +| `localpv.image.repository` | Image repository for LocalPV Provisioner | `openebs/localpv-provisioner` | +| `localpv.image.pullPolicy` | Image pull policy for LocalPV Provisioner | `IfNotPresent` | +| `localpv.image.tag` | Image tag for LocalPV Provisioner | `4.4.0` | +| `localpv.updateStrategy.type` | Update strategy for LocalPV Provisioner | `RollingUpdate` | +| `localpv.annotations` | Annotations for LocalPV Provisioner metadata | `""` | +| `localpv.podAnnotations` | Annotations for LocalPV Provisioner pods metadata | `""` | +| `localpv.privileged` | Run LocalPV Provisioner with extra privileges | `true` | +| `localpv.resources` | Resource and request and limit for containers | `""` | +| `localpv.podLabels` | Appends labels to the pods | `""` | +| `localpv.nodeSelector` | Nodeselector for LocalPV Provisioner pods | `""` | +| `localpv.tolerations` | LocalPV Provisioner pod toleration values | `""` | +| `localpv.securityContext` | Seurity context for container | `""` | +| `localpv.healthCheck.initialDelaySeconds` | Delay before liveness probe is initiated | `30` | +| `localpv.healthCheck.periodSeconds` | How often to perform the liveness probe | `60` | +| `localpv.replicas` | No. of LocalPV Provisioner replica | `1` | +| `localpv.enableLeaderElection` | Enable leader election | `true` | +| `localpv.affinity` | LocalPV Provisioner pod affinity | `{}` | +| `localpv.priorityClassName` | Sets priorityClassName in pod | `""` | +| `rbac.create` | Enable RBAC Resources | `true` | +| `rbac.pspEnabled` | Create pod security policy resources | `false` | + + +A YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml --namespace openebs openebs-localpv/localpv-provisioner +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/charts/mayastor/charts/localpv-provisioner/templates/NOTES.txt b/charts/mayastor/charts/localpv-provisioner/templates/NOTES.txt new file mode 100644 index 0000000..54ab551 --- /dev/null +++ b/charts/mayastor/charts/localpv-provisioner/templates/NOTES.txt @@ -0,0 +1,9 @@ +The OpenEBS Dynamic LocalPV Provisioner has been installed. +Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +Get started with the Dynamic LocalPV Provisioner Quickstart guide at: +https://github.com/openebs/dynamic-localpv-provisioner/blob/develop/docs/quickstart.md + +For more information, visit our Slack at https://kubernetes.slack.com/messages/openebs or view +the OpenEBS documentation online at https://openebs.io/docs diff --git a/charts/mayastor/charts/localpv-provisioner/templates/_helpers.tpl b/charts/mayastor/charts/localpv-provisioner/templates/_helpers.tpl new file mode 100644 index 0000000..d49f162 --- /dev/null +++ b/charts/mayastor/charts/localpv-provisioner/templates/_helpers.tpl @@ -0,0 +1,91 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "localpv.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified localpv provisioner 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 "localpv.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "localpv.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Meta labels +*/}} +{{- define "localpv.common.metaLabels" -}} +chart: {{ template "localpv.chart" . }} +heritage: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "localpv.selectorLabels" -}} +app: {{ template "localpv.name" . }} +release: {{ .Release.Name }} +component: {{ .Values.localpv.name | quote }} +{{- end -}} + +{{/* +Component labels +*/}} +{{- define "localpv.componentLabels" -}} +openebs.io/component-name: openebs-{{ .Values.localpv.name }} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "localpv.labels" -}} +{{ include "localpv.common.metaLabels" . }} +{{ include "localpv.selectorLabels" . }} +{{ include "localpv.componentLabels" . }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "localpv.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "localpv.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Creates the tolerations based on the global tolerations, with early eviction +Usage: +{{ include "tolerations_with_early_eviction" . }} +*/}} +{{- define "tolerations_with_early_eviction" -}} +{{- if .Values.earlyEvictionTolerations }} + {{- toYaml .Values.earlyEvictionTolerations | nindent 8 }} +{{- end }} +{{- if .Values.localpv.tolerations }} + {{- toYaml .Values.localpv.tolerations | nindent 8 }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/localpv-provisioner/templates/deployment.yaml b/charts/mayastor/charts/localpv-provisioner/templates/deployment.yaml new file mode 100644 index 0000000..c631cf0 --- /dev/null +++ b/charts/mayastor/charts/localpv-provisioner/templates/deployment.yaml @@ -0,0 +1,133 @@ +{{- if .Values.localpv.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.localpv.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + {{- include "localpv.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.localpv.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 8 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 8 }} + {{- end }} + {{- with .Values.localpv.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.loggingLabels}} + {{ toYaml . | nindent 8 -}} + {{- end}} + spec: + {{- if .Values.localpv.priorityClassName }} + priorityClassName: {{ tpl .Values.localpv.priorityClassName . }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "localpv.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ template "localpv.fullname" . }} + image: "{{ with .Values.localpv.image.registry | default .Values.global.imageRegistry | trimSuffix "/" }}{{ . }}/{{ end }}{{ .Values.localpv.image.repository }}:{{ .Values.localpv.image.tag }}" + imagePullPolicy: {{ .Values.localpv.image.pullPolicy }} + resources: +{{ toYaml .Values.localpv.resources | indent 10 }} + env: + # OPENEBS_IO_K8S_MASTER enables openebs provisioner to connect to K8s + # based on this address. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_K8S_MASTER + # value: "http://10.128.0.12:8080" + # OPENEBS_IO_KUBE_CONFIG enables openebs provisioner to connect to K8s + # based on this config. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_KUBE_CONFIG + # value: "/home/ubuntu/.kube/config" + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + # OPENEBS_SERVICE_ACCOUNT provides the service account of this pod as + # environment variable + - name: OPENEBS_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + # OPENEBS_IO_BASE_PATH is the environment variable that provides the + # default base path on the node where host-path PVs will be provisioned. + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + {{- if .Values.analytics.gaId }} + - name: GA_ID + value: {{ .Values.analytics.gaId | quote }} + {{- end }} + {{- if .Values.analytics.gaKey }} + - name: GA_KEY + value: {{ .Values.analytics.gaKey | quote }} + {{- end }} + - name: OPENEBS_IO_BASE_PATH + value: "{{ .Values.localpv.basePath }}" + - name: OPENEBS_IO_HELPER_IMAGE + value: "{{ with .Values.helperPod.image.registry | default .Values.global.imageRegistry | trimSuffix "/" }}{{ . }}/{{ end }}{{ .Values.helperPod.image.repository }}:{{ .Values.helperPod.image.tag }}" + - name: OPENEBS_IO_HELPER_POD_HOST_NETWORK + value: "{{ .Values.helperPod.hostNetwork }}" + - name: OPENEBS_IO_INSTALLER_TYPE + value: "localpv-charts-helm" + # LEADER_ELECTION_ENABLED is used to enable/disable leader election. By default + # leader election is enabled. + - name: LEADER_ELECTION_ENABLED + value: "{{ .Values.localpv.enableLeaderElection }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $index, $secret := .Values.imagePullSecrets}}{{if $index}},{{end}}{{ $secret.name }}{{- end}}" +{{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can't be used here with pgrep (>15 chars).A regular expression + # that matches the entire command name has to specified. + # Anchor `^` : matches any string that starts with `provisioner-loc` + # `.*`: matches any string that has `provisioner-loc` followed by zero or more char + livenessProbe: + exec: + command: + - sh + - -c + - test `pgrep -c "^provisioner-loc.*"` = 1 + initialDelaySeconds: {{ .Values.localpv.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.localpv.healthCheck.periodSeconds }} +{{- if .Values.localpv.nodeSelector }} + nodeSelector: +{{ toYaml .Values.localpv.nodeSelector | indent 8 }} +{{- end }} +{{- if $tolerations := include "tolerations_with_early_eviction" . }} + tolerations: {{ $tolerations }} +{{- end }} +{{- if .Values.localpv.affinity }} + affinity: +{{ toYaml .Values.localpv.affinity | indent 8 }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/localpv-provisioner/templates/hostpath-class.yaml b/charts/mayastor/charts/localpv-provisioner/templates/hostpath-class.yaml new file mode 100644 index 0000000..7c5be71 --- /dev/null +++ b/charts/mayastor/charts/localpv-provisioner/templates/hostpath-class.yaml @@ -0,0 +1,43 @@ +{{- if .Values.hostpathClass.enabled }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ tpl (.Values.hostpathClass.name) .}} + annotations: + openebs.io/cas-type: local + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" +{{- if or .Values.localpv.basePath .Values.hostpathClass.basePath }} + - name: BasePath + value: {{ tpl (.Values.hostpathClass.basePath | default .Values.localpv.basePath | quote) . }} +{{- end }} +{{- if .Values.hostpathClass.nodeAffinityLabels }} + - name: NodeAffinityLabels + list: +{{ toYaml .Values.hostpathClass.nodeAffinityLabels | indent 10 }} +{{- end }} +{{- if .Values.hostpathClass.xfsQuota.enabled }} + - name: XFSQuota + enabled: "{{ .Values.hostpathClass.xfsQuota.enabled }}" + data: + softLimitGrace: "{{ .Values.hostpathClass.xfsQuota.softLimitGrace }}" + hardLimitGrace: "{{ .Values.hostpathClass.xfsQuota.hardLimitGrace }}" +{{- end }} +{{- if .Values.hostpathClass.ext4Quota.enabled }} + - name: EXT4Quota + enabled: "{{ .Values.hostpathClass.ext4Quota.enabled }}" + data: + softLimitGrace: "{{ .Values.hostpathClass.ext4Quota.softLimitGrace }}" + hardLimitGrace: "{{ .Values.hostpathClass.ext4Quota.hardLimitGrace }}" +{{- end }} +{{- if .Values.hostpathClass.isDefaultClass }} + storageclass.kubernetes.io/is-default-class: "true" +{{- end }} +{{- if .Values.extraLabels }} + labels: {{- toYaml .Values.extraLabels | nindent 4 -}} +{{- end }} +provisioner: openebs.io/local +volumeBindingMode: WaitForFirstConsumer +reclaimPolicy: {{ .Values.hostpathClass.reclaimPolicy }} +{{- end }} diff --git a/charts/mayastor/charts/localpv-provisioner/templates/psp.yaml b/charts/mayastor/charts/localpv-provisioner/templates/psp.yaml new file mode 100644 index 0000000..ed97e28 --- /dev/null +++ b/charts/mayastor/charts/localpv-provisioner/templates/psp.yaml @@ -0,0 +1,33 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} +spec: + privileged: {{ .Values.localpv.privileged }} + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: true + hostPorts: + - min: 0 + max: 65535 + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/charts/mayastor/charts/localpv-provisioner/templates/rbac.yaml b/charts/mayastor/charts/localpv-provisioner/templates/rbac.yaml new file mode 100644 index 0000000..aeeed85 --- /dev/null +++ b/charts/mayastor/charts/localpv-provisioner/templates/rbac.yaml @@ -0,0 +1,117 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "localpv.serviceAccountName" . }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- if .Values.rbac.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} +rules: +- apiGroups: ["*"] + resources: ["nodes"] + verbs: ["get", "list", "watch"] +- apiGroups: ["*"] + resources: ["namespaces", "pods", "events", "endpoints"] + verbs: ["*"] +- apiGroups: ["*"] + resources: ["resourcequotas", "limitranges"] + verbs: ["list", "watch"] +- apiGroups: ["*"] + resources: ["storageclasses", "persistentvolumeclaims", "persistentvolumes"] + verbs: ["*"] +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: [ "get", "list", "create", "update", "delete", "patch"] +- apiGroups: ["openebs.io"] + resources: [ "*"] + verbs: ["*" ] +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "create", "update"] +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "localpv.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "localpv.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- if .Values.rbac.pspEnabled }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "localpv.fullname" . }}-psp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- if .Values.extraLabels -}} + {{- toYaml .Values.extraLabels | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "localpv.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "localpv.serviceAccountName" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/localpv-provisioner/values.yaml b/charts/mayastor/charts/localpv-provisioner/values.yaml new file mode 100644 index 0000000..3528c5c --- /dev/null +++ b/charts/mayastor/charts/localpv-provisioner/values.yaml @@ -0,0 +1,144 @@ +# Default values for localpv. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +global: + # Used as default image registry, values supplied by localpv.image.registry + # and helperPod.image.registry override this value. + imageRegistry: "docker.io" + +rbac: + # rbac.create: `true` if rbac resources should be created + create: true + # rbac.pspEnabled: `true` if PodSecurityPolicy resources should be created + pspEnabled: false + +earlyEvictionTolerations: + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 5 + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 5 + +localpv: + name: localpv-provisioner + enabled: true + image: + registry: "" + repository: openebs/provisioner-localpv + tag: 4.4.0 + pullPolicy: IfNotPresent + updateStrategy: + type: RollingUpdate + # If set to false, containers created by the localpv provisioner will run without extra privileges. + privileged: true + annotations: {} + podAnnotations: {} + ## Labels to be added to localpv provisioner deployment pods + podLabels: + name: openebs-localpv-provisioner + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + replicas: 1 + enableLeaderElection: true + basePath: "/var/openebs/local" + resources: + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + nodeSelector: {} + tolerations: [] + affinity: {} + securityContext: {} + ## Sets priorityClassName in pod + priorityClassName: "" + +imagePullSecrets: +# - name: img-pull-secret +podSecurityContext: {} +# fsGroup: 2000 + +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: + +hostpathClass: + # Name of the default hostpath StorageClass + name: openebs-hostpath + # If true, enables creation of the openebs-hostpath StorageClass + enabled: true + # Available reclaim policies: Delete/Retain, defaults: Delete. + reclaimPolicy: Delete + # If true, sets the openebs-hostpath StorageClass as the default StorageClass + isDefaultClass: false + # Path on the host where local volumes of this storage class are mounted under. + # NOTE: If not specified, this defaults to the value of localpv.basePath. + basePath: "" + # Custom node affinity label(s) for example "openebs.io/node-affinity-value" + # that will be used instead of hostnames + # This helps in cases where the hostname changes when the node is removed and + # added back with the disks still intact. + # Example: + # nodeAffinityLabels: + # - "openebs.io/node-affinity-key-1" + # - "openebs.io/node-affinity-key-2" + nodeAffinityLabels: [] + # Prerequisite: XFS Quota requires an XFS filesystem mounted with + # the 'pquota' or 'prjquota' mount option. + xfsQuota: + # If true, enables XFS project quota + enabled: false + # Detailed configuration options for XFS project quota. + # If XFS Quota is enabled with the default values, the usage limit + # is set at the storage capacity specified in the PVC. + softLimitGrace: "0%" + hardLimitGrace: "0%" + # Prerequisite: EXT4 Quota requires an EXT4 filesystem mounted with + # the 'prjquota' mount option. + ext4Quota: + # If true, enables XFS project quota + enabled: false + # Detailed configuration options for EXT4 project quota. + # If EXT4 Quota is enabled with the default values, the usage limit + # is set at the storage capacity specified in the PVC. + softLimitGrace: "0%" + hardLimitGrace: "0%" + +helperPod: + image: + registry: "" + repository: openebs/linux-utils + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 4.3.0 + hostNetwork: false + +# Additional labels to add to all chart resources +extraLabels: {} + +loggingLabels: + openebs.io/logging: "true" + +analytics: + enabled: true + # Specify in hours the duration after which a ping event needs to be sent. + pingInterval: "24h" diff --git a/charts/mayastor/charts/loki/.helmignore b/charts/mayastor/charts/loki/.helmignore new file mode 100644 index 0000000..6d90723 --- /dev/null +++ b/charts/mayastor/charts/loki/.helmignore @@ -0,0 +1,32 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ + +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ + +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ + +# Other +doc.yaml +README.tpl +README.md.gotmpl +ci +CHANGELOG.md diff --git a/charts/mayastor/charts/loki/Chart.lock b/charts/mayastor/charts/loki/Chart.lock new file mode 100644 index 0000000..1cc42f7 --- /dev/null +++ b/charts/mayastor/charts/loki/Chart.lock @@ -0,0 +1,12 @@ +dependencies: +- name: minio + repository: https://charts.min.io/ + version: 5.4.0 +- name: grafana-agent-operator + repository: https://grafana.github.io/helm-charts + version: 0.5.1 +- name: rollout-operator + repository: https://grafana.github.io/helm-charts + version: 0.24.0 +digest: sha256:beb08aeb31a1fa6b88c326b307c9960ca5fc5032892f7acd5deae6b859884638 +generated: "2025-02-26T01:09:19.861074559Z" diff --git a/charts/mayastor/charts/loki/Chart.yaml b/charts/mayastor/charts/loki/Chart.yaml new file mode 100644 index 0000000..9f43ee6 --- /dev/null +++ b/charts/mayastor/charts/loki/Chart.yaml @@ -0,0 +1,32 @@ +apiVersion: v2 +appVersion: 3.4.2 +dependencies: +- alias: minio + condition: minio.enabled + name: minio + repository: https://charts.min.io/ + version: 5.4.0 +- alias: grafana-agent-operator + condition: monitoring.selfMonitoring.grafanaAgent.installOperator + name: grafana-agent-operator + repository: https://grafana.github.io/helm-charts + version: 0.5.1 +- alias: rollout_operator + condition: rollout_operator.enabled + name: rollout-operator + repository: https://grafana.github.io/helm-charts + version: 0.24.0 +description: Helm chart for Grafana Loki and Grafana Enterprise Logs supporting monolithic, + simple scalable, and microservices modes. +home: https://grafana.github.io/helm-charts +icon: https://grafana.com/docs/loki/latest/logo_and_name.png +maintainers: +- name: trevorwhitney +- name: jeschkies +name: loki +sources: +- https://github.com/grafana/loki +- https://grafana.com/oss/loki/ +- https://grafana.com/docs/loki/latest/ +type: application +version: 6.29.0 diff --git a/charts/mayastor/charts/loki/Makefile b/charts/mayastor/charts/loki/Makefile new file mode 100644 index 0000000..373086a --- /dev/null +++ b/charts/mayastor/charts/loki/Makefile @@ -0,0 +1,84 @@ +.DEFAULT_GOAL := all +.PHONY: lint lint-yaml install-distributed install-single-binary uninstall update-chart update + +# Optional image override, example: make install-distributed IMAGE=grafana/loki:2.9.0 +IMAGE ?= + +# Optional helm arguments, example: make install-distributed ARGS="--set loki.auth.enabled=true" +ARGS ?= + +# Default arguments to disable affinity for testing +DEFAULT_ARGS = --set gateway.affinity=null \ + --set ingester.affinity=null \ + --set distributor.affinity=null \ + --set querier.affinity=null \ + --set queryFrontend.affinity=null \ + --set queryScheduler.affinity=null \ + --set indexGateway.affinity=null \ + --set compactor.affinity=null \ + --set ruler.affinity=null \ + --set backend.affinity=null \ + --set read.affinity=null \ + --set write.affinity=null \ + --set singleBinary.affinity=null \ + --set memcachedChunks.affinity=null \ + --set memcachedFrontend.affinity=null \ + --set memcachedIndexQueries.affinity=null \ + --set memcachedMetadata.affinity=null \ + --set memcachedResults.affinity=null \ + --set global.podAntiAffinity=null \ + --set global.podAntiAffinityTopologyKey=null + +# Generate image override flag if IMAGE is provided +IMAGE_FLAG = $(if $(IMAGE),\ + $(eval PARTS=$(subst :, ,$(IMAGE)))\ + $(eval REPO_PARTS=$(subst /, ,$(word 1,$(PARTS))))\ + $(eval TAG=$(word 2,$(PARTS)))\ + $(eval REPO_COUNT=$(words $(REPO_PARTS)))\ + $(if $(filter 3,$(REPO_COUNT)),\ + --set loki.image.registry=$(word 1,$(REPO_PARTS))/$(word 2,$(REPO_PARTS)) --set loki.image.repository=$(word 3,$(REPO_PARTS)),\ + --set loki.image.registry=$(word 1,$(REPO_PARTS)) --set loki.image.repository=$(word 2,$(REPO_PARTS))\ + ) --set loki.image.tag=$(TAG),) + +lint: lint-yaml + +lint-yaml: + yamllint -c $(CURDIR)/src/.yamllint.yaml $(CURDIR)/src + +# Helm chart installation targets +install-distributed: + helm upgrade --install loki . \ + -f distributed-values.yaml \ + --create-namespace \ + --namespace loki \ + $(DEFAULT_ARGS) \ + $(IMAGE_FLAG) \ + $(ARGS) + +install-single-binary: + helm upgrade --install loki . \ + -f single-binary-values.yaml \ + --create-namespace \ + --namespace loki \ + $(DEFAULT_ARGS) \ + $(IMAGE_FLAG) \ + $(ARGS) + +# Uninstall Loki helm release and optionally delete the namespace +uninstall: + helm uninstall loki --namespace loki + kubectl delete namespace loki --ignore-not-found + +# Update Helm chart dependencies +update-chart: + helm dependency update . + +# Update existing installation with latest changes +update: + @if [ "$$(helm get values loki -n loki -o yaml | grep "deploymentMode: Distributed")" ]; then \ + echo "Updating distributed deployment..."; \ + helm upgrade loki . -f distributed-values.yaml --namespace loki $(DEFAULT_ARGS) $(IMAGE_FLAG) $(ARGS); \ + else \ + echo "Updating single binary deployment..."; \ + helm upgrade loki . -f single-binary-values.yaml --namespace loki $(DEFAULT_ARGS) $(IMAGE_FLAG) $(ARGS); \ + fi diff --git a/charts/mayastor/charts/loki/README.md b/charts/mayastor/charts/loki/README.md new file mode 100644 index 0000000..5dcf910 --- /dev/null +++ b/charts/mayastor/charts/loki/README.md @@ -0,0 +1,65 @@ +# loki + +![Version: 6.29.0](https://img.shields.io/badge/Version-6.29.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 3.4.2](https://img.shields.io/badge/AppVersion-3.4.2-informational?style=flat-square) + +Helm chart for Grafana Loki and Grafana Enterprise Logs supporting monolithic, simple scalable, and microservices modes. + +## Source Code + +* +* +* + +## Requirements + +| Repository | Name | Version | +|------------|------|---------| +| https://charts.min.io/ | minio(minio) | 5.4.0 | +| https://grafana.github.io/helm-charts | grafana-agent-operator(grafana-agent-operator) | 0.5.1 | +| https://grafana.github.io/helm-charts | rollout_operator(rollout-operator) | 0.24.0 | + +Find more information in the Loki Helm Chart [documentation](https://grafana.com/docs/loki/next/installation/helm). + +## Contributing and releasing + +If you made any changes to the [Chart.yaml](https://github.com/grafana/loki/blob/main/production/helm/loki/Chart.yaml) or [values.yaml](https://github.com/grafana/loki/blob/main/production/helm/loki/values.yaml) run `make helm-docs` from the root of the repository to update the documentation and commit the changed files. + +Futhermore, please add an entry to the [CHANGELOG.md](./CHANGELOG.md) file about what you changed. This file has a header that looks like this: + +``` +[//]: # ( : do not remove this line. This locator is used by the CI pipeline to automatically create a changelog entry for each new Loki release. Add other chart versions and respective changelog entries bellow this line.) +```` + +Place your changes as a bulleted list below this header. The helm chart is automatically released once a week, at which point the `CHANGELOG.md` file will be updated to reflect the release of all changes between this header the the header of the previous version as the changes for that weeks release. For example, if the weekly release will be `1.21.0`, and the `CHANGELOG.md` file has the following entries: + +``` +[//]: # ( : do not remove this line. This locator is used by the CI pipeline to automatically create a changelog entry for each new Loki release. Add other chart versions and respective changelog entries bellow this line.) + +- [CHANGE] Changed the thing +- [FEATURE] Cool new feature + +## 1.20.0 + +- [BUGFIX] Fixed the bug +``` + +Then the weekly release will create a `CHANGELOG.md` with the following content: +``` +[//]: # ( : do not remove this line. This locator is used by the CI pipeline to automatically create a changelog entry for each new Loki release. Add other chart versions and respective changelog entries bellow this line.) + +## 1.21.0 + +- [CHANGE] Changed the thing +- [FEATURE] Cool new feature + +## 1.20.0 + +- [BUGFIX] Fixed the bug +``` + +#### Versioning + +Normally contributors need _not_ bump the version nor update the [CHANGELOG.md](https://github.com/grafana/loki/blob/main/production/helm/loki/CHANGELOG.md). A new version of the Chart will follow this cadence: +- Automatic weekly releases +- Releases that coincide with Loki/GEL releases +- Manual releases when necessary (ie. to address a CVE or critical bug) diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/.helmignore b/charts/mayastor/charts/loki/charts/grafana-agent-operator/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/Chart.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/Chart.yaml new file mode 100644 index 0000000..ef2b820 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +appVersion: 0.44.2 +description: A Helm chart for Grafana Agent Operator +home: https://grafana.com/docs/agent/v0.44/ +icon: https://raw.githubusercontent.com/grafana/agent/v0.44.2/docs/sources/assets/logo_and_name.png +maintainers: +- email: grafana-agent-team@googlegroups.com + name: Grafana Agent Team +name: grafana-agent-operator +sources: +- https://github.com/grafana/agent/tree/v0.44.2/static/operator +type: application +version: 0.5.1 diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/README.md b/charts/mayastor/charts/loki/charts/grafana-agent-operator/README.md new file mode 100644 index 0000000..57589a7 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/README.md @@ -0,0 +1,82 @@ +# grafana-agent-operator + +![Version: 0.5.1](https://img.shields.io/badge/Version-0.5.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.44.2](https://img.shields.io/badge/AppVersion-0.44.2-informational?style=flat-square) + +A Helm chart for Grafana Agent Operator + +⚠️ **Please create issues relating to this Helm chart in the [Agent](https://github.com/grafana/agent/issues) repo.** + +## Source Code + +* + +Note that this chart does not provision custom resources like `GrafanaAgent` and `MetricsInstance` (formerly `PrometheusInstance`) or any `*Monitor` resources. + +To learn how to deploy these resources, please see Grafana's [Agent Operator getting started guide](https://grafana.com/docs/agent/latest/operator/getting-started/). + +## CRDs + +The CRDs are synced into this chart manually (for now) from the Grafana Agent [GitHub repo](https://github.com/grafana/agent/tree/main/operations/agent-static-operator/crds). To learn more about how Helm manages CRDs, please see [Custom Resource Definitions](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/) from the Helm docs. + +## Get Repo Info + +```console +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release grafana/grafana-agent-operator +``` + +## Uninstalling the Chart + +To uninstall/delete the my-release deployment: + +```console +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Upgrading an existing Release to a new major version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an incompatible breaking change needing manual actions. Until this chart's version reaches `v1.0`, there are no promises of backwards compatibility. + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | Pod affinity configuration | +| annotations | object | `{}` | Annotations for the Deployment | +| containerSecurityContext | object | `{}` | Container security context (allowPrivilegeEscalation, etc.) | +| extraArgs | list | `[]` | List of additional cli arguments to configure agent-operator (example: `--log.level`) | +| fullnameOverride | string | `""` | Overrides the chart's computed fullname | +| global.commonLabels | object | `{}` | Common labels for all object directly managed by this chart. | +| hostAliases | list | `[]` | hostAliases to add | +| image.pullPolicy | string | `"IfNotPresent"` | Image pull policy | +| image.pullSecrets | list | `[]` | Image pull secrets | +| image.registry | string | `"docker.io"` | Image registry | +| image.repository | string | `"grafana/agent-operator"` | Image repo | +| image.tag | string | `"v0.44.2"` | Image tag | +| kubeletService | object | `{"namespace":"default","serviceName":"kubelet"}` | If both are set, Agent Operator will create and maintain a service for scraping kubelets https://grafana.com/docs/agent/latest/operator/getting-started/#monitor-kubelets | +| nameOverride | string | `""` | Overrides the chart's name | +| nodeSelector | object | `{}` | nodeSelector configuration | +| podAnnotations | object | `{}` | Annotations for the Deployment Pods | +| podLabels | object | `{}` | Annotations for the Deployment Pods | +| podSecurityContext | object | `{}` | Pod security context (runAsUser, etc.) | +| rbac.create | bool | `true` | Toggle to create ClusterRole and ClusterRoleBinding | +| rbac.podSecurityPolicyName | string | `""` | Name of a PodSecurityPolicy to use in the ClusterRole. If unset, no PodSecurityPolicy is used. | +| resources | object | `{}` | Resource limits and requests config | +| serviceAccount.create | bool | `true` | Toggle to create ServiceAccount | +| serviceAccount.name | string | `nil` | Service account name | +| test.image.registry | string | `"docker.io"` | Test image registry | +| test.image.repository | string | `"library/busybox"` | Test image repo | +| test.image.tag | string | `"latest"` | Test image tag | +| tolerations | list | `[]` | Tolerations applied to Pods | diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/README.md.gotmpl b/charts/mayastor/charts/loki/charts/grafana-agent-operator/README.md.gotmpl new file mode 100644 index 0000000..3dce97a --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/README.md.gotmpl @@ -0,0 +1,52 @@ +{{ template "chart.header" . }} + +{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} + +{{ template "chart.description" . }} + +⚠️ **Please create issues relating to this Helm chart in the [Agent](https://github.com/grafana/agent/issues) repo.** + +{{ template "chart.sourcesSection" . }} + +{{ template "chart.requirementsSection" . }} + +Note that this chart does not provision custom resources like `GrafanaAgent` and `MetricsInstance` (formerly `PrometheusInstance`) or any `*Monitor` resources. + +To learn how to deploy these resources, please see Grafana's [Agent Operator getting started guide](https://grafana.com/docs/agent/latest/operator/getting-started/). + +## CRDs + +The CRDs are synced into this chart manually (for now) from the Grafana Agent [GitHub repo](https://github.com/grafana/agent/tree/main/operations/agent-static-operator/crds). To learn more about how Helm manages CRDs, please see [Custom Resource Definitions](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/) from the Helm docs. + +## Get Repo Info + +```console +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release grafana/grafana-agent-operator +``` + +## Uninstalling the Chart + +To uninstall/delete the my-release deployment: + +```console +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Upgrading an existing Release to a new major version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an incompatible breaking change needing manual actions. Until this chart's version reaches `v1.0`, there are no promises of backwards compatibility. + +{{ template "chart.valuesSection" . }} diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_podmonitors.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_podmonitors.yaml new file mode 100644 index 0000000..153677b --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_podmonitors.yaml @@ -0,0 +1,424 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: podmonitors.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: PodMonitor + listKind: PodMonitorList + plural: podmonitors + shortNames: + - pmon + singular: podmonitor + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + attachMetadata: + properties: + node: + type: boolean + type: object + jobLabel: + type: string + labelLimit: + format: int64 + type: integer + labelNameLengthLimit: + format: int64 + type: integer + labelValueLengthLimit: + format: int64 + type: integer + namespaceSelector: + properties: + any: + type: boolean + matchNames: + items: + type: string + type: array + type: object + podMetricsEndpoints: + items: + properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHttp2: + type: boolean + filterRunning: + type: boolean + followRedirects: + type: boolean + honorLabels: + type: boolean + honorTimestamps: + type: boolean + interval: + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + params: + additionalProperties: + items: + type: string + type: array + type: object + path: + type: string + port: + type: string + proxyUrl: + type: string + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + enum: + - http + - https + type: string + scrapeTimeout: + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + type: boolean + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + type: array + podTargetLabels: + items: + type: string + type: array + sampleLimit: + format: int64 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + targetLimit: + format: int64 + type: integer + required: + - podMetricsEndpoints + - selector + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_probes.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_probes.yaml new file mode 100644 index 0000000..13fc36f --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_probes.yaml @@ -0,0 +1,458 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: probes.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: Probe + listKind: ProbeList + plural: probes + shortNames: + - prb + singular: probe + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + interval: + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + jobName: + type: string + labelLimit: + format: int64 + type: integer + labelNameLengthLimit: + format: int64 + type: integer + labelValueLengthLimit: + format: int64 + type: integer + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + module: + type: string + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + prober: + properties: + path: + default: /probe + type: string + proxyUrl: + type: string + scheme: + enum: + - http + - https + type: string + url: + type: string + required: + - url + type: object + sampleLimit: + format: int64 + type: integer + scrapeTimeout: + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetLimit: + format: int64 + type: integer + targets: + properties: + ingress: + properties: + namespaceSelector: + properties: + any: + type: boolean + matchNames: + items: + type: string + type: array + type: object + relabelingConfigs: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + staticConfig: + properties: + labels: + additionalProperties: + type: string + type: object + relabelingConfigs: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + static: + items: + type: string + type: array + type: object + type: object + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + type: boolean + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_servicemonitors.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_servicemonitors.yaml new file mode 100644 index 0000000..ff62f8f --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.coreos.com_servicemonitors.yaml @@ -0,0 +1,436 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: servicemonitors.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: ServiceMonitor + listKind: ServiceMonitorList + plural: servicemonitors + shortNames: + - smon + singular: servicemonitor + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + attachMetadata: + properties: + node: + type: boolean + type: object + endpoints: + items: + properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenFile: + type: string + bearerTokenSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHttp2: + type: boolean + filterRunning: + type: boolean + followRedirects: + type: boolean + honorLabels: + type: boolean + honorTimestamps: + type: boolean + interval: + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + metricRelabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + params: + additionalProperties: + items: + type: string + type: array + type: object + path: + type: string + port: + type: string + proxyUrl: + type: string + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + scheme: + enum: + - http + - https + type: string + scrapeTimeout: + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + type: object + type: array + jobLabel: + type: string + labelLimit: + format: int64 + type: integer + labelNameLengthLimit: + format: int64 + type: integer + labelValueLengthLimit: + format: int64 + type: integer + namespaceSelector: + properties: + any: + type: boolean + matchNames: + items: + type: string + type: array + type: object + podTargetLabels: + items: + type: string + type: array + sampleLimit: + format: int64 + type: integer + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + targetLabels: + items: + type: string + type: array + targetLimit: + format: int64 + type: integer + required: + - endpoints + - selector + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_grafanaagents.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_grafanaagents.yaml new file mode 100644 index 0000000..4ec31d6 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_grafanaagents.yaml @@ -0,0 +1,3711 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: grafanaagents.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: GrafanaAgent + listKind: GrafanaAgentList + plural: grafanaagents + singular: grafanaagent + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + apiServer: + properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + type: string + bearerTokenFile: + type: string + host: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + required: + - host + type: object + configMaps: + items: + type: string + type: array + configReloaderImage: + type: string + configReloaderVersion: + type: string + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + disableReporting: + default: false + type: boolean + disableSupportBundle: + default: false + type: boolean + enableConfigReadAPI: + default: false + type: boolean + image: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + integrations: + properties: + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + logFormat: + type: string + logLevel: + type: string + logs: + properties: + clients: + items: + properties: + backoffConfig: + properties: + maxPeriod: + type: string + maxRetries: + type: integer + minPeriod: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + batchSize: + type: integer + batchWait: + type: string + bearerToken: + type: string + bearerTokenFile: + type: string + externalLabels: + additionalProperties: + type: string + type: object + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyUrl: + type: string + tenantId: + type: string + timeout: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + url: + type: string + required: + - url + type: object + type: array + enforcedNamespaceLabel: + type: string + ignoreNamespaceSelectors: + type: boolean + instanceNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + instanceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + logsExternalLabelName: + type: string + type: object + metrics: + properties: + arbitraryFSAccessThroughSMs: + properties: + deny: + type: boolean + type: object + enforcedNamespaceLabel: + type: string + enforcedSampleLimit: + format: int64 + type: integer + enforcedTargetLimit: + format: int64 + type: integer + externalLabels: + additionalProperties: + type: string + type: object + ignoreNamespaceSelectors: + type: boolean + instanceNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + instanceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + metricsExternalLabelName: + type: string + overrideHonorLabels: + type: boolean + overrideHonorTimestamps: + type: boolean + remoteWrite: + items: + properties: + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + type: string + bearerTokenFile: + type: string + headers: + additionalProperties: + type: string + type: object + metadataConfig: + properties: + send: + type: boolean + sendInterval: + type: string + type: object + name: + type: string + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyUrl: + type: string + queueConfig: + properties: + batchSendDeadline: + type: string + capacity: + type: integer + maxBackoff: + type: string + maxRetries: + type: integer + maxSamplesPerSend: + type: integer + maxShards: + type: integer + minBackoff: + type: string + minShards: + type: integer + retryOnRateLimit: + type: boolean + type: object + remoteTimeout: + type: string + sigv4: + properties: + accessKey: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + profile: + type: string + region: + type: string + roleARN: + type: string + secretKey: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + url: + type: string + writeRelabelConfigs: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + required: + - url + type: object + type: array + replicaExternalLabelName: + type: string + replicas: + format: int32 + type: integer + scrapeInterval: + type: string + scrapeTimeout: + type: string + shards: + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + type: object + paused: + type: boolean + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: object + portName: + type: string + priorityClassName: + type: string + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + runtimeClassName: + type: string + secrets: + items: + type: string + type: array + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + storage: + properties: + disableMountSubPath: + type: boolean + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + volumeClaimTemplate: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + status: + properties: + accessModes: + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + phase: + type: string + type: object + type: object + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + version: + type: string + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + served: true + storage: true diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_integrations.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_integrations.yaml new file mode 100644 index 0000000..960b2f7 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_integrations.yaml @@ -0,0 +1,810 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: integrations.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: Integration + listKind: IntegrationList + plural: integrations + singular: integration + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + config: + type: object + x-kubernetes-preserve-unknown-fields: true + configMaps: + items: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + name: + type: string + secrets: + items: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + type: + properties: + allNodes: + type: boolean + unique: + type: boolean + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - config + - name + - type + type: object + type: object + served: true + storage: true diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_logsinstances.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_logsinstances.yaml new file mode 100644 index 0000000..517bb30 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_logsinstances.yaml @@ -0,0 +1,299 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: logsinstances.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: LogsInstance + listKind: LogsInstanceList + plural: logsinstances + singular: logsinstance + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + additionalScrapeConfigs: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clients: + items: + properties: + backoffConfig: + properties: + maxPeriod: + type: string + maxRetries: + type: integer + minPeriod: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + batchSize: + type: integer + batchWait: + type: string + bearerToken: + type: string + bearerTokenFile: + type: string + externalLabels: + additionalProperties: + type: string + type: object + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyUrl: + type: string + tenantId: + type: string + timeout: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + url: + type: string + required: + - url + type: object + type: array + podLogsNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + podLogsSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + targetConfig: + properties: + syncPeriod: + type: string + type: object + type: object + type: object + served: true + storage: true diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_metricsinstances.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_metricsinstances.yaml new file mode 100644 index 0000000..610193f --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_metricsinstances.yaml @@ -0,0 +1,495 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: metricsinstances.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: MetricsInstance + listKind: MetricsInstanceList + plural: metricsinstances + singular: metricsinstance + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + additionalScrapeConfigs: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxWALTime: + type: string + minWALTime: + type: string + podMonitorNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + podMonitorSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + probeNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + probeSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + remoteFlushDeadline: + type: string + remoteWrite: + items: + properties: + basicAuth: + properties: + password: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + type: string + bearerTokenFile: + type: string + headers: + additionalProperties: + type: string + type: object + metadataConfig: + properties: + send: + type: boolean + sendInterval: + type: string + type: object + name: + type: string + oauth2: + properties: + clientId: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + type: object + scopes: + items: + type: string + type: array + tokenUrl: + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyUrl: + type: string + queueConfig: + properties: + batchSendDeadline: + type: string + capacity: + type: integer + maxBackoff: + type: string + maxRetries: + type: integer + maxSamplesPerSend: + type: integer + maxShards: + type: integer + minBackoff: + type: string + minShards: + type: integer + retryOnRateLimit: + type: boolean + type: object + remoteTimeout: + type: string + sigv4: + properties: + accessKey: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + profile: + type: string + region: + type: string + roleARN: + type: string + secretKey: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + url: + type: string + writeRelabelConfigs: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + required: + - url + type: object + type: array + serviceMonitorNamespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + serviceMonitorSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + walTruncateFrequency: + type: string + writeStaleOnShutdown: + type: boolean + type: object + type: object + served: true + storage: true diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_podlogs.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_podlogs.yaml new file mode 100644 index 0000000..f22d051 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/crds/monitoring.grafana.com_podlogs.yaml @@ -0,0 +1,308 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: podlogs.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: PodLogs + listKind: PodLogsList + plural: podlogs + singular: podlogs + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + jobLabel: + type: string + namespaceSelector: + properties: + any: + type: boolean + matchNames: + items: + type: string + type: array + type: object + pipelineStages: + items: + properties: + cri: + type: object + docker: + type: object + drop: + properties: + dropCounterReason: + type: string + expression: + type: string + longerThan: + type: string + olderThan: + type: string + source: + type: string + value: + type: string + type: object + json: + properties: + expressions: + additionalProperties: + type: string + type: object + source: + type: string + type: object + labelAllow: + items: + type: string + type: array + labelDrop: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + limit: + properties: + burst: + type: integer + drop: + type: boolean + rate: + type: integer + type: object + match: + properties: + action: + type: string + dropCounterReason: + type: string + pipelineName: + type: string + selector: + type: string + stages: + type: string + required: + - selector + type: object + metrics: + additionalProperties: + properties: + action: + type: string + buckets: + items: + type: string + type: array + countEntryBytes: + type: boolean + description: + type: string + matchAll: + type: boolean + maxIdleDuration: + type: string + prefix: + type: string + source: + type: string + type: + type: string + value: + type: string + required: + - action + - type + type: object + type: object + multiline: + properties: + firstLine: + type: string + maxLines: + type: integer + maxWaitTime: + type: string + required: + - firstLine + type: object + output: + properties: + source: + type: string + required: + - source + type: object + pack: + properties: + ingestTimestamp: + type: boolean + labels: + items: + type: string + type: array + required: + - labels + type: object + regex: + properties: + expression: + type: string + source: + type: string + required: + - expression + type: object + replace: + properties: + expression: + type: string + replace: + type: string + source: + type: string + required: + - expression + type: object + template: + properties: + source: + type: string + template: + type: string + required: + - source + - template + type: object + tenant: + properties: + label: + type: string + source: + type: string + value: + type: string + type: object + timestamp: + properties: + actionOnFailure: + type: string + fallbackFormats: + items: + type: string + type: array + format: + type: string + location: + type: string + source: + type: string + required: + - format + - source + type: object + type: object + type: array + podTargetLabels: + items: + type: string + type: array + relabelings: + items: + properties: + action: + default: replace + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + format: int64 + type: integer + regex: + type: string + replacement: + type: string + separator: + type: string + sourceLabels: + items: + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + type: string + type: object + type: array + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + required: + - selector + type: object + type: object + served: true + storage: true diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/_helpers.tpl b/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/_helpers.tpl new file mode 100644 index 0000000..e374499 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/_helpers.tpl @@ -0,0 +1,70 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "ga-operator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +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 "ga-operator.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "ga-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "ga-operator.labels" -}} +{{ include "ga-operator.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: operator +helm.sh/chart: {{ include "ga-operator.chart" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels }} +{{- end }} +{{- with .Values.global.commonLabels }} +{{ toYaml . }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "ga-operator.selectorLabels" -}} +app.kubernetes.io/name: {{ include "ga-operator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "ga-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "ga-operator.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrole.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrole.yaml new file mode 100644 index 0000000..08ad58c --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrole.yaml @@ -0,0 +1,62 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "ga-operator.fullname" . }} + labels: +{{ include "ga-operator.labels" . | indent 4 }} +rules: +- apiGroups: [monitoring.grafana.com] + resources: + - grafanaagents + - metricsinstances + - logsinstances + - podlogs + - integrations + verbs: [get, list, watch] +- apiGroups: [monitoring.grafana.com] + resources: + - grafanaagents/finalizers + - metricsinstances/finalizers + - logsinstances/finalizers + - podlogs/finalizers + - integrations/finalizers + verbs: [get, list, watch, update] +- apiGroups: [monitoring.coreos.com] + resources: + - podmonitors + - probes + - servicemonitors + verbs: [get, list, watch] +- apiGroups: [monitoring.coreos.com] + resources: + - podmonitors/finalizers + - probes/finalizers + - servicemonitors/finalizers + verbs: [get, list, watch, update] +- apiGroups: [""] + resources: + - namespaces + - nodes + verbs: [get, list, watch] +- apiGroups: [""] + resources: + - secrets + - services + - configmaps + - endpoints + verbs: [get, list, watch, create, update, patch, delete] +- apiGroups: ["apps"] + resources: + - statefulsets + - daemonsets + - deployments + verbs: [get, list, watch, create, update, patch, delete] +{{- with .Values.rbac.podSecurityPolicyName }} +- apiGroups: [policy] + resources: + - podsecuritypolicies + verbs: [use] + resourceNames: [ {{ . }} ] +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrolebinding.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrolebinding.yaml new file mode 100644 index 0000000..372d310 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/operator-clusterrolebinding.yaml @@ -0,0 +1,17 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "ga-operator.fullname" . }} + labels: +{{ include "ga-operator.labels" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "ga-operator.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "ga-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end -}} + diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/operator-deployment.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/operator-deployment.yaml new file mode 100644 index 0000000..3367db1 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/operator-deployment.yaml @@ -0,0 +1,79 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "ga-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "ga-operator.labels" . | indent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: 1 + selector: + matchLabels: +{{ include "ga-operator.selectorLabels" . | indent 6 }} + template: + metadata: + labels: +{{ include "ga-operator.selectorLabels" . | indent 8 }} +{{- with .Values.podLabels }} +{{- toYaml . | nindent 8 }} +{{- end }} +{{- with .Values.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + serviceAccountName: {{ template "ga-operator.serviceAccountName" . }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ include "ga-operator.name" . }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- if or (and .Values.kubeletService.namespace .Values.kubeletService.serviceName) (.Values.extraArgs) }} + args: + {{- if and .Values.kubeletService.namespace .Values.kubeletService.serviceName }} + - --kubelet-service={{ .Values.kubeletService.namespace }}/{{ .Values.kubeletService.serviceName }} + {{- end }} + {{- if .Values.extraArgs }} + {{- range .Values.extraArgs }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.image.pullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/operator-serviceaccount.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/operator-serviceaccount.yaml new file mode 100644 index 0000000..1f9b207 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/operator-serviceaccount.yaml @@ -0,0 +1,10 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "ga-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "ga-operator.labels" . | indent 4 }} +{{- end -}} + diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/tests/test-grafanaagent.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/tests/test-grafanaagent.yaml new file mode 100644 index 0000000..4001da4 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/templates/tests/test-grafanaagent.yaml @@ -0,0 +1,118 @@ +apiVersion: monitoring.grafana.com/v1alpha1 +kind: GrafanaAgent +metadata: + name: grafana-agent-test + labels: + app: grafana-agent-test + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +spec: + image: "{{ .Values.image.registry }}/grafana/agent:{{ .Values.image.tag }}" + logLevel: info + serviceAccountName: grafana-agent-test-sa + metrics: + instanceSelector: + matchLabels: + agent: grafana-agent-test + +--- + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: grafana-agent-test-sa + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: grafana-agent-test-cr + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +rules: +- apiGroups: + - "" + resources: + - nodes + - nodes/proxy + - nodes/metrics + - services + - endpoints + - pods + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- nonResourceURLs: + - /metrics + - /metrics/cadvisor + verbs: + - get + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: grafana-agent-test-crb + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: grafana-agent-test-cr +subjects: +- kind: ServiceAccount + name: grafana-agent-test-sa + namespace: {{ .Release.Namespace }} + +--- + +apiVersion: monitoring.grafana.com/v1alpha1 +kind: MetricsInstance +metadata: + name: primary-test + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed + labels: + agent: grafana-agent-test +spec: {} + +--- + +apiVersion: v1 +kind: Pod +metadata: + name: grafana-agent-test-probe + annotations: + "helm.sh/hook": test + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +spec: + containers: + - name: busybox + image: "{{ .Values.test.image.registry }}/{{ .Values.test.image.repository }}:{{ .Values.test.image.tag }}" + command: ['wget'] + args: ['grafana-agent-test-operated:8080/-/healthy'] + # Wait for GrafanaAgent CR + initContainers: + - name: sleep + image: "{{ .Values.test.image.registry }}/{{ .Values.test.image.repository }}:{{ .Values.test.image.tag }}" + command: ['sleep', '60'] + restartPolicy: Never diff --git a/charts/mayastor/charts/loki/charts/grafana-agent-operator/values.yaml b/charts/mayastor/charts/loki/charts/grafana-agent-operator/values.yaml new file mode 100644 index 0000000..0fb0fc9 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/grafana-agent-operator/values.yaml @@ -0,0 +1,84 @@ +global: + # -- Common labels for all object directly managed by this chart. + commonLabels: {} + +# -- Overrides the chart's name +nameOverride: "" + +# -- Overrides the chart's computed fullname +fullnameOverride: "" + +# -- Annotations for the Deployment +annotations: {} + +# -- Annotations for the Deployment Pods +podAnnotations: {} + +# -- Annotations for the Deployment Pods +podLabels: {} + +# -- Pod security context (runAsUser, etc.) +podSecurityContext: {} + +# -- Container security context (allowPrivilegeEscalation, etc.) +containerSecurityContext: {} + +rbac: + # -- Toggle to create ClusterRole and ClusterRoleBinding + create: true + # -- Name of a PodSecurityPolicy to use in the ClusterRole. If unset, no PodSecurityPolicy is used. + podSecurityPolicyName: '' + +serviceAccount: + # -- Toggle to create ServiceAccount + create: true + # -- Service account name + name: + +image: + # -- Image registry + registry: docker.io + # -- Image repo + repository: grafana/agent-operator + # -- Image tag + tag: v0.44.2 + # -- Image pull policy + pullPolicy: IfNotPresent + # -- Image pull secrets + pullSecrets: [] + +test: + image: + # -- Test image registry + registry: docker.io + # -- Test image repo + repository: library/busybox + # -- Test image tag + tag: latest + +# -- hostAliases to add +hostAliases: [] +# - ip: 1.2.3.4 +# hostnames: +# - domain.tld + +# -- If both are set, Agent Operator will create and maintain a service for scraping kubelets +# https://grafana.com/docs/agent/latest/operator/getting-started/#monitor-kubelets +kubeletService: + namespace: default + serviceName: kubelet + +# -- List of additional cli arguments to configure agent-operator (example: `--log.level`) +extraArgs: [] + +# -- Resource limits and requests config +resources: {} + +# -- nodeSelector configuration +nodeSelector: {} + +# -- Tolerations applied to Pods +tolerations: [] + +# -- Pod affinity configuration +affinity: {} diff --git a/charts/mayastor/charts/loki/charts/minio/.helmignore b/charts/mayastor/charts/loki/charts/minio/.helmignore new file mode 100644 index 0000000..a9fe727 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +# OWNERS file for Kubernetes +OWNERS \ No newline at end of file diff --git a/charts/mayastor/charts/loki/charts/minio/Chart.yaml b/charts/mayastor/charts/loki/charts/minio/Chart.yaml new file mode 100644 index 0000000..827787e --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +appVersion: RELEASE.2024-12-18T13-15-44Z +description: High Performance Object Storage +home: https://min.io +icon: https://min.io/resources/img/logo/MINIO_wordmark.png +keywords: +- minio +- storage +- object-storage +- s3 +- cluster +maintainers: +- email: dev@minio.io + name: MinIO, Inc +name: minio +sources: +- https://github.com/minio/minio +version: 5.4.0 diff --git a/charts/mayastor/charts/loki/charts/minio/README.md b/charts/mayastor/charts/loki/charts/minio/README.md new file mode 100644 index 0000000..a1d5c99 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/README.md @@ -0,0 +1,264 @@ +# MinIO Community Helm Chart + +[![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io) [![license](https://img.shields.io/badge/license-AGPL%20V3-blue)](https://github.com/minio/minio/blob/master/LICENSE) + +MinIO is a High Performance Object Storage released under GNU Affero General Public License v3.0. It is API compatible with Amazon S3 cloud storage service. Use MinIO to build high performance infrastructure for machine learning, analytics and application data workloads. + +| IMPORTANT | +| -------------------------- | +| This Helm chart is community built, maintained, and supported. MinIO does not guarantee support for any given bug, feature request, or update referencing this chart.

MinIO publishes a separate [MinIO Kubernetes Operator and Tenant Helm Chart](https://github.com/minio/operator/tree/master/helm) that is officially maintained and supported. MinIO strongly recommends using the MinIO Kubernetes Operator for production deployments. See [Deploy Operator With Helm](https://min.io/docs/minio/kubernetes/upstream/operations/install-deploy-manage/deploy-operator-helm.html?ref=github) for additional documentation. | + +## Introduction + +This chart bootstraps MinIO Cluster on [Kubernetes](http://kubernetes.io) using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Helm cli with Kubernetes cluster configured. +- PV provisioner support in the underlying infrastructure. (We recommend using ) +- Use Kubernetes version v1.19 and later for best experience. + +## Configure MinIO Helm repo + +```bash +helm repo add minio https://charts.min.io/ +``` + +### Installing the Chart + +Install this chart using: + +```bash +helm install --namespace minio --set rootUser=rootuser,rootPassword=rootpass123 --generate-name minio/minio +``` + +The command deploys MinIO on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +### Installing the Chart (toy-setup) + +Minimal toy setup for testing purposes can be deployed using: + +```bash +helm install --set resources.requests.memory=512Mi --set replicas=1 --set persistence.enabled=false --set mode=standalone --set rootUser=rootuser,rootPassword=rootpass123 --generate-name minio/minio +``` + +### Upgrading the Chart + +You can use Helm to update MinIO version in a live release. Assuming your release is named as `my-release`, get the values using the command: + +```bash +helm get values my-release > old_values.yaml +``` + +Then change the field `image.tag` in `old_values.yaml` file with MinIO image tag you want to use. Now update the chart using + +```bash +helm upgrade -f old_values.yaml my-release minio/minio +``` + +Default upgrade strategies are specified in the `values.yaml` file. Update these fields if you'd like to use a different strategy. + +### Configuration + +Refer the [Values file](./values.yaml) for all the possible config fields. + +You can specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```bash +helm install --name my-release --set persistence.size=1Ti minio/minio +``` + +The above command deploys MinIO server with a 1Ti backing persistent volume. + +Alternately, you can provide a YAML file that specifies parameter values while installing the chart. For example, + +```bash +helm install --name my-release -f values.yaml minio/minio +``` + +### Persistence + +This chart provisions a PersistentVolumeClaim and mounts corresponding persistent volume to default location `/export`. You'll need physical storage available in the Kubernetes cluster for this to work. If you'd rather use `emptyDir`, disable PersistentVolumeClaim by: + +```bash +helm install --set persistence.enabled=false minio/minio +``` + +> *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."* + +### Existing PersistentVolumeClaim + +If a Persistent Volume Claim already exists, specify it during installation. + +1. Create the PersistentVolume +2. Create the PersistentVolumeClaim +3. Install the chart + +```bash +helm install --set persistence.existingClaim=PVC_NAME minio/minio +``` + +### NetworkPolicy + +To enable network policy for MinIO, +install [a networking plugin that implements the Kubernetes +NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin), +and set `networkPolicy.enabled` to `true`. + +For Kubernetes v1.5 & v1.6, you must also turn on NetworkPolicy by setting +the DefaultDeny namespace annotation. Note: this will enforce policy for *all* pods in the namespace: + +``` +kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}" +``` + +When using `Cilium` as a CNI in your cluster, please edit the `flavor` field to `cilium`. + +With NetworkPolicy enabled, traffic will be limited to just port 9000. + +For more precise policy, set `networkPolicy.allowExternal=true`. This will +only allow pods with the generated client label to connect to MinIO. +This label will be displayed in the output of a successful install. + +### Existing secret + +Instead of having this chart create the secret for you, you can supply a preexisting secret, much +like an existing PersistentVolumeClaim. + +First, create the secret: + +```bash +kubectl create secret generic my-minio-secret --from-literal=rootUser=foobarbaz --from-literal=rootPassword=foobarbazqux +``` + +Then install the chart, specifying that you want to use an existing secret: + +```bash +helm install --set existingSecret=my-minio-secret minio/minio +``` + +The following fields are expected in the secret: + +| .data.\ in Secret | Corresponding variable | Description | Required | +|:------------------------|:-----------------------|:---------------|:---------| +| `rootUser` | `rootUser` | Root user. | yes | +| `rootPassword` | `rootPassword` | Root password. | yes | + +All corresponding variables will be ignored in values file. + +### Configure TLS + +To enable TLS for MinIO containers, acquire TLS certificates from a CA or create self-signed certificates. While creating / acquiring certificates ensure the corresponding domain names are set as per the standard [DNS naming conventions](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-identity) in a Kubernetes StatefulSet (for a distributed MinIO setup). Then create a secret using + +```bash +kubectl create secret generic tls-ssl-minio --from-file=path/to/private.key --from-file=path/to/public.crt +``` + +Then install the chart, specifying that you want to use the TLS secret: + +```bash +helm install --set tls.enabled=true,tls.certSecret=tls-ssl-minio minio/minio +``` + +### Installing certificates from third party CAs + +MinIO can connect to other servers, including MinIO nodes or other server types such as NATs and Redis. If these servers use certificates that were not registered with a known CA, add trust for these certificates to MinIO Server by bundling these certificates into a Kubernetes secret and providing it to Helm via the `trustedCertsSecret` value. If `.Values.tls.enabled` is `true` and you're installing certificates for third party CAs, remember to include MinIO's own certificate with key `public.crt`, if it also needs to be trusted. + +For instance, given that TLS is enabled and you need to add trust for MinIO's own CA and for the CA of a Keycloak server, a Kubernetes secret can be created from the certificate files using `kubectl`: + +``` +kubectl -n minio create secret generic minio-trusted-certs --from-file=public.crt --from-file=keycloak.crt +``` + +If TLS is not enabled, you would need only the third party CA: + +``` +kubectl -n minio create secret generic minio-trusted-certs --from-file=keycloak.crt +``` + +The name of the generated secret can then be passed to Helm using a values file or the `--set` parameter: + +``` +trustedCertsSecret: "minio-trusted-certs" + +or + +--set trustedCertsSecret=minio-trusted-certs +``` + +### Create buckets after install + +Install the chart, specifying the buckets you want to create after install: + +```bash +helm install --set buckets[0].name=bucket1,buckets[0].policy=none,buckets[0].purge=false minio/minio +``` + +Description of the configuration parameters used above - + +- `buckets[].name` - name of the bucket to create, must be a string with length > 0 +- `buckets[].policy` - can be one of none|download|upload|public +- `buckets[].purge` - purge if bucket exists already + +### Create policies after install + +Install the chart, specifying the policies you want to create after install: + +```bash +helm install --set policies[0].name=mypolicy,policies[0].statements[0].resources[0]='arn:aws:s3:::bucket1',policies[0].statements[0].actions[0]='s3:ListBucket',policies[0].statements[0].actions[1]='s3:GetObject' minio/minio +``` + +Description of the configuration parameters used above - + +- `policies[].name` - name of the policy to create, must be a string with length > 0 +- `policies[].statements[]` - list of statements, includes actions and resources +- `policies[].statements[].resources[]` - list of resources that applies the statement +- `policies[].statements[].actions[]` - list of actions granted + +### Create user after install + +Install the chart, specifying the users you want to create after install: + +```bash +helm install --set users[0].accessKey=accessKey,users[0].secretKey=secretKey,users[0].policy=none,users[1].accessKey=accessKey2,users[1].secretRef=existingSecret,users[1].secretKey=password,users[1].policy=none minio/minio +``` + +Description of the configuration parameters used above - + +- `users[].accessKey` - accessKey of user +- `users[].secretKey` - secretKey of usersecretRef +- `users[].existingSecret` - secret name that contains the secretKey of user +- `users[].existingSecretKey` - data key in existingSecret secret containing the secretKey +- `users[].policy` - name of the policy to assign to user + +### Create service account after install + +Install the chart, specifying the service accounts you want to create after install: + +```bash +helm install --set svcaccts[0].accessKey=accessKey,svcaccts[0].secretKey=secretKey,svcaccts[0].user=parentUser,svcaccts[1].accessKey=accessKey2,svcaccts[1].secretRef=existingSecret,svcaccts[1].secretKey=password,svcaccts[1].user=parentUser2 minio/minio +``` + +Description of the configuration parameters used above - + +- `svcaccts[].accessKey` - accessKey of service account +- `svcaccts[].secretKey` - secretKey of svcacctsecretRef +- `svcaccts[].existingSecret` - secret name that contains the secretKey of service account +- `svcaccts[].existingSecretKey` - data key in existingSecret secret containing the secretKey +- `svcaccts[].user` - name of the parent user to assign to service account + +## Uninstalling the Chart + +Assuming your release is named as `my-release`, delete it using the command: + +```bash +helm delete my-release +``` + +or + +```bash +helm uninstall my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. diff --git a/charts/mayastor/charts/loki/charts/minio/templates/NOTES.txt b/charts/mayastor/charts/loki/charts/minio/templates/NOTES.txt new file mode 100644 index 0000000..ba51b4c --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/NOTES.txt @@ -0,0 +1,43 @@ +{{- if eq .Values.service.type "ClusterIP" "NodePort" }} +MinIO can be accessed via port {{ .Values.service.port }} on the following DNS name from within your cluster: +{{ template "minio.fullname" . }}.{{ .Release.Namespace }}.{{ .Values.clusterDomain }} + +To access MinIO from localhost, run the below commands: + + 1. export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + + 2. kubectl port-forward $POD_NAME 9000 --namespace {{ .Release.Namespace }} + +Read more about port forwarding here: http://kubernetes.io/docs/user-guide/kubectl/kubectl_port-forward/ + +You can now access MinIO server on http://localhost:9000. Follow the below steps to connect to MinIO server with mc client: + + 1. Download the MinIO mc client - https://min.io/docs/minio/linux/reference/minio-mc.html#quickstart + + 2. export MC_HOST_{{ template "minio.fullname" . }}-local=http://$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "minio.secretName" . }} -o jsonpath="{.data.rootUser}" | base64 --decode):$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "minio.secretName" . }} -o jsonpath="{.data.rootPassword}" | base64 --decode)@localhost:{{ .Values.service.port }} + + 3. mc ls {{ template "minio.fullname" . }}-local + +{{- end }} +{{- if eq .Values.service.type "LoadBalancer" }} +MinIO can be accessed via port {{ .Values.service.port }} on an external IP address. Get the service external IP address by: +kubectl get svc --namespace {{ .Release.Namespace }} -l app={{ template "minio.fullname" . }} + +Note that the public IP may take a couple of minutes to be available. + +You can now access MinIO server on http://:9000. Follow the below steps to connect to MinIO server with mc client: + + 1. Download the MinIO mc client - https://min.io/docs/minio/linux/reference/minio-mc.html#quickstart + + 2. export MC_HOST_{{ template "minio.fullname" . }}-local=http://$(kubectl get secret {{ template "minio.secretName" . }} --namespace {{ .Release.Namespace }} -o jsonpath="{.data.rootUser}" | base64 --decode):$(kubectl get secret {{ template "minio.secretName" . }} -o jsonpath="{.data.rootPassword}" | base64 --decode)@:{{ .Values.service.port }} + + 3. mc ls {{ template "minio.fullname" . }} + +Alternately, you can use your browser or the MinIO SDK to access the server - https://min.io/docs/minio/linux/reference/minio-server/minio-server.html +{{- end }} + +{{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} +Note: Since NetworkPolicy is enabled, only pods with label +{{ template "minio.fullname" . }}-client=true" +will be able to connect to this minio cluster. +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/_helper_create_bucket.txt b/charts/mayastor/charts/loki/charts/minio/templates/_helper_create_bucket.txt new file mode 100644 index 0000000..83b8dcb --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/_helper_create_bucket.txt @@ -0,0 +1,122 @@ +#!/bin/sh +set -e # Have script exit in the event of a failed command. + +{{- if .Values.configPathmc }} +MC_CONFIG_DIR="{{ .Values.configPathmc }}" +MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}" +{{- else }} +MC="/usr/bin/mc --insecure" +{{- end }} + +# connectToMinio +# Use a check-sleep-check loop to wait for MinIO service to be available +connectToMinio() { + SCHEME=$1 + ATTEMPTS=0 + LIMIT=29 # Allow 30 attempts + set -e # fail if we can't read the keys. + ACCESS=$(cat /config/rootUser) + SECRET=$(cat /config/rootPassword) + set +e # The connections to minio are allowed to fail. + echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" + MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" + $MC_COMMAND + STATUS=$? + until [ $STATUS = 0 ]; do + ATTEMPTS=$(expr $ATTEMPTS + 1) + echo \"Failed attempts: $ATTEMPTS\" + if [ $ATTEMPTS -gt $LIMIT ]; then + exit 1 + fi + sleep 2 # 1 second intervals between attempts + $MC_COMMAND + STATUS=$? + done + set -e # reset `e` as active + return 0 +} + +# checkBucketExists ($bucket) +# Check if the bucket exists, by using the exit code of `mc ls` +checkBucketExists() { + BUCKET=$1 + CMD=$(${MC} stat myminio/$BUCKET >/dev/null 2>&1) + return $? +} + +# createBucket ($bucket, $policy, $purge) +# Ensure bucket exists, purging if asked to +createBucket() { + BUCKET=$1 + POLICY=$2 + PURGE=$3 + VERSIONING=$4 + OBJECTLOCKING=$5 + + # Purge the bucket, if set & exists + # Since PURGE is user input, check explicitly for `true` + if [ $PURGE = true ]; then + if checkBucketExists $BUCKET; then + echo "Purging bucket '$BUCKET'." + set +e # don't exit if this fails + ${MC} rm -r --force myminio/$BUCKET + set -e # reset `e` as active + else + echo "Bucket '$BUCKET' does not exist, skipping purge." + fi + fi + + # Create the bucket if it does not exist and set objectlocking if enabled (NOTE: versioning will be not changed if OBJECTLOCKING is set because it enables versioning to the Buckets created) + if ! checkBucketExists $BUCKET; then + if [ ! -z $OBJECTLOCKING ]; then + if [ $OBJECTLOCKING = true ]; then + echo "Creating bucket with OBJECTLOCKING '$BUCKET'" + ${MC} mb --with-lock myminio/$BUCKET + elif [ $OBJECTLOCKING = false ]; then + echo "Creating bucket '$BUCKET'" + ${MC} mb myminio/$BUCKET + fi + elif [ -z $OBJECTLOCKING ]; then + echo "Creating bucket '$BUCKET'" + ${MC} mb myminio/$BUCKET + else + echo "Bucket '$BUCKET' already exists." + fi + fi + + # set versioning for bucket if objectlocking is disabled or not set + if [ $OBJECTLOCKING = false ]; then + if [ ! -z $VERSIONING ]; then + if [ $VERSIONING = true ]; then + echo "Enabling versioning for '$BUCKET'" + ${MC} version enable myminio/$BUCKET + elif [ $VERSIONING = false ]; then + echo "Suspending versioning for '$BUCKET'" + ${MC} version suspend myminio/$BUCKET + fi + fi + else + echo "Bucket '$BUCKET' versioning unchanged." + fi + + # At this point, the bucket should exist, skip checking for existence + # Set policy on the bucket + echo "Setting policy of bucket '$BUCKET' to '$POLICY'." + ${MC} anonymous set $POLICY myminio/$BUCKET +} + +# Try connecting to MinIO instance +{{- if .Values.tls.enabled }} +scheme=https +{{- else }} +scheme=http +{{- end }} +connectToMinio $scheme + +{{ if .Values.buckets }} +{{ $global := . }} +# Create the buckets +{{- range .Values.buckets }} +createBucket {{ tpl .name $global }} {{ .policy | default "none" | quote }} {{ .purge | default false }} {{ .versioning | default false }} {{ .objectlocking | default false }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/_helper_create_policy.txt b/charts/mayastor/charts/loki/charts/minio/templates/_helper_create_policy.txt new file mode 100644 index 0000000..aa58495 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/_helper_create_policy.txt @@ -0,0 +1,75 @@ +#!/bin/sh +set -e ; # Have script exit in the event of a failed command. + +{{- if .Values.configPathmc }} +MC_CONFIG_DIR="{{ .Values.configPathmc }}" +MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}" +{{- else }} +MC="/usr/bin/mc --insecure" +{{- end }} + +# connectToMinio +# Use a check-sleep-check loop to wait for MinIO service to be available +connectToMinio() { + SCHEME=$1 + ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts + set -e ; # fail if we can't read the keys. + ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ; + set +e ; # The connections to minio are allowed to fail. + echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ; + MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ; + $MC_COMMAND ; + STATUS=$? ; + until [ $STATUS = 0 ] + do + ATTEMPTS=`expr $ATTEMPTS + 1` ; + echo \"Failed attempts: $ATTEMPTS\" ; + if [ $ATTEMPTS -gt $LIMIT ]; then + exit 1 ; + fi ; + sleep 2 ; # 1 second intervals between attempts + $MC_COMMAND ; + STATUS=$? ; + done ; + set -e ; # reset `e` as active + return 0 +} + +# checkPolicyExists ($policy) +# Check if the policy exists, by using the exit code of `mc admin policy info` +checkPolicyExists() { + POLICY=$1 + CMD=$(${MC} admin policy info myminio $POLICY > /dev/null 2>&1) + return $? +} + +# createPolicy($name, $filename) +createPolicy () { + NAME=$1 + FILENAME=$2 + + # Create the name if it does not exist + echo "Checking policy: $NAME (in /config/$FILENAME.json)" + if ! checkPolicyExists $NAME ; then + echo "Creating policy '$NAME'" + else + echo "Policy '$NAME' already exists." + fi + ${MC} admin policy create myminio $NAME /config/$FILENAME.json + +} + +# Try connecting to MinIO instance +{{- if .Values.tls.enabled }} +scheme=https +{{- else }} +scheme=http +{{- end }} +connectToMinio $scheme + +{{ if .Values.policies }} +# Create the policies +{{- range $idx, $policy := .Values.policies }} +createPolicy {{ $policy.name }} policy_{{ $idx }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/_helper_create_svcacct.txt b/charts/mayastor/charts/loki/charts/minio/templates/_helper_create_svcacct.txt new file mode 100644 index 0000000..5c8aec4 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/_helper_create_svcacct.txt @@ -0,0 +1,106 @@ +#!/bin/sh +set -e ; # Have script exit in the event of a failed command. + +{{- if .Values.configPathmc }} +MC_CONFIG_DIR="{{ .Values.configPathmc }}" +MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}" +{{- else }} +MC="/usr/bin/mc --insecure" +{{- end }} + +# AccessKey and secretkey credentials file are added to prevent shell execution errors caused by special characters. +# Special characters for example : ',",<,>,{,} +MINIO_ACCESSKEY_SECRETKEY_TMP="/tmp/accessKey_and_secretKey_svcacct_tmp" + +# connectToMinio +# Use a check-sleep-check loop to wait for MinIO service to be available +connectToMinio() { + SCHEME=$1 + ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts + set -e ; # fail if we can't read the keys. + ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ; + set +e ; # The connections to minio are allowed to fail. + echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ; + MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ; + $MC_COMMAND ; + STATUS=$? ; + until [ $STATUS = 0 ] + do + ATTEMPTS=`expr $ATTEMPTS + 1` ; + echo \"Failed attempts: $ATTEMPTS\" ; + if [ $ATTEMPTS -gt $LIMIT ]; then + exit 1 ; + fi ; + sleep 2 ; # 2 second intervals between attempts + $MC_COMMAND ; + STATUS=$? ; + done ; + set -e ; # reset `e` as active + return 0 +} + +# checkSvcacctExists () +# Check if the svcacct exists, by using the exit code of `mc admin user svcacct info` +checkSvcacctExists() { + CMD=$(${MC} admin user svcacct info myminio $(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) > /dev/null 2>&1) + return $? +} + +# createSvcacct ($user) +createSvcacct () { + USER=$1 + FILENAME=$2 + #check accessKey_and_secretKey_tmp file + if [[ ! -f $MINIO_ACCESSKEY_SECRETKEY_TMP ]];then + echo "credentials file does not exist" + return 1 + fi + if [[ $(cat $MINIO_ACCESSKEY_SECRETKEY_TMP|wc -l) -ne 2 ]];then + echo "credentials file is invalid" + rm -f $MINIO_ACCESSKEY_SECRETKEY_TMP + return 1 + fi + SVCACCT=$(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) + # Create the svcacct if it does not exist + if ! checkSvcacctExists ; then + echo "Creating svcacct '$SVCACCT'" + # Check if policy file is define + if [ -z $FILENAME ]; then + ${MC} admin user svcacct add --access-key $(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) --secret-key $(tail -n1 $MINIO_ACCESSKEY_SECRETKEY_TMP) myminio $USER + else + ${MC} admin user svcacct add --access-key $(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) --secret-key $(tail -n1 $MINIO_ACCESSKEY_SECRETKEY_TMP) --policy /config/$FILENAME.json myminio $USER + fi + else + echo "Svcacct '$SVCACCT' already exists." + fi + #clean up credentials files. + rm -f $MINIO_ACCESSKEY_SECRETKEY_TMP +} + +# Try connecting to MinIO instance +{{- if .Values.tls.enabled }} +scheme=https +{{- else }} +scheme=http +{{- end }} +connectToMinio $scheme + +{{ if .Values.svcaccts }} +{{ $global := . }} +# Create the svcaccts +{{- range $idx, $svc := .Values.svcaccts }} +echo {{ tpl .accessKey $global }} > $MINIO_ACCESSKEY_SECRETKEY_TMP +{{- if .existingSecret }} +cat /config/secrets-svc/{{ tpl .existingSecret $global }}/{{ tpl .existingSecretKey $global }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP +# Add a new line if it doesn't exist +echo >> $MINIO_ACCESSKEY_SECRETKEY_TMP +{{ else }} +echo {{ .secretKey }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP +{{- end }} +{{- if $svc.policy}} +createSvcacct {{ .user }} svc_policy_{{ $idx }} +{{ else }} +createSvcacct {{ .user }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/_helper_create_user.txt b/charts/mayastor/charts/loki/charts/minio/templates/_helper_create_user.txt new file mode 100644 index 0000000..bfb79be --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/_helper_create_user.txt @@ -0,0 +1,107 @@ +#!/bin/sh +set -e ; # Have script exit in the event of a failed command. + +{{- if .Values.configPathmc }} +MC_CONFIG_DIR="{{ .Values.configPathmc }}" +MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}" +{{- else }} +MC="/usr/bin/mc --insecure" +{{- end }} + +# AccessKey and secretkey credentials file are added to prevent shell execution errors caused by special characters. +# Special characters for example : ',",<,>,{,} +MINIO_ACCESSKEY_SECRETKEY_TMP="/tmp/accessKey_and_secretKey_tmp" + +# connectToMinio +# Use a check-sleep-check loop to wait for MinIO service to be available +connectToMinio() { + SCHEME=$1 + ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts + set -e ; # fail if we can't read the keys. + ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ; + set +e ; # The connections to minio are allowed to fail. + echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ; + MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ; + $MC_COMMAND ; + STATUS=$? ; + until [ $STATUS = 0 ] + do + ATTEMPTS=`expr $ATTEMPTS + 1` ; + echo \"Failed attempts: $ATTEMPTS\" ; + if [ $ATTEMPTS -gt $LIMIT ]; then + exit 1 ; + fi ; + sleep 2 ; # 1 second intervals between attempts + $MC_COMMAND ; + STATUS=$? ; + done ; + set -e ; # reset `e` as active + return 0 +} + +# checkUserExists () +# Check if the user exists, by using the exit code of `mc admin user info` +checkUserExists() { + CMD=$(${MC} admin user info myminio $(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) > /dev/null 2>&1) + return $? +} + +# createUser ($policy) +createUser() { + POLICY=$1 + #check accessKey_and_secretKey_tmp file + if [[ ! -f $MINIO_ACCESSKEY_SECRETKEY_TMP ]];then + echo "credentials file does not exist" + return 1 + fi + if [[ $(cat $MINIO_ACCESSKEY_SECRETKEY_TMP|wc -l) -ne 2 ]];then + echo "credentials file is invalid" + rm -f $MINIO_ACCESSKEY_SECRETKEY_TMP + return 1 + fi + USER=$(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) + # Create the user if it does not exist + if ! checkUserExists ; then + echo "Creating user '$USER'" + cat $MINIO_ACCESSKEY_SECRETKEY_TMP | ${MC} admin user add myminio + else + echo "User '$USER' already exists." + fi + #clean up credentials files. + rm -f $MINIO_ACCESSKEY_SECRETKEY_TMP + + # set policy for user + if [ ! -z $POLICY -a $POLICY != " " ] ; then + echo "Adding policy '$POLICY' for '$USER'" + set +e ; # policy already attach errors out, allow it. + ${MC} admin policy attach myminio $POLICY --user=$USER + set -e + else + echo "User '$USER' has no policy attached." + fi +} + +# Try connecting to MinIO instance +{{- if .Values.tls.enabled }} +scheme=https +{{- else }} +scheme=http +{{- end }} +connectToMinio $scheme + +{{ if .Values.users }} +{{ $global := . }} +# Create the users +{{- range .Values.users }} +echo {{ tpl .accessKey $global }} > $MINIO_ACCESSKEY_SECRETKEY_TMP +{{- if .existingSecret }} +cat /config/secrets/{{ tpl .existingSecret $global }}/{{ tpl .existingSecretKey $global }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP +# Add a new line if it doesn't exist +echo >> $MINIO_ACCESSKEY_SECRETKEY_TMP +createUser {{ .policy }} +{{ else }} +echo {{ .secretKey }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP +createUser {{ .policy }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/_helper_custom_command.txt b/charts/mayastor/charts/loki/charts/minio/templates/_helper_custom_command.txt new file mode 100644 index 0000000..b583a77 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/_helper_custom_command.txt @@ -0,0 +1,58 @@ +#!/bin/sh +set -e ; # Have script exit in the event of a failed command. + +{{- if .Values.configPathmc }} +MC_CONFIG_DIR="{{ .Values.configPathmc }}" +MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}" +{{- else }} +MC="/usr/bin/mc --insecure" +{{- end }} + +# connectToMinio +# Use a check-sleep-check loop to wait for MinIO service to be available +connectToMinio() { + SCHEME=$1 + ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts + set -e ; # fail if we can't read the keys. + ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ; + set +e ; # The connections to minio are allowed to fail. + echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ; + MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ; + $MC_COMMAND ; + STATUS=$? ; + until [ $STATUS = 0 ] + do + ATTEMPTS=`expr $ATTEMPTS + 1` ; + echo \"Failed attempts: $ATTEMPTS\" ; + if [ $ATTEMPTS -gt $LIMIT ]; then + exit 1 ; + fi ; + sleep 2 ; # 1 second intervals between attempts + $MC_COMMAND ; + STATUS=$? ; + done ; + set -e ; # reset `e` as active + return 0 +} + +# runCommand ($@) +# Run custom mc command +runCommand() { + ${MC} "$@" + return $? +} + +# Try connecting to MinIO instance +{{- if .Values.tls.enabled }} +scheme=https +{{- else }} +scheme=http +{{- end }} +connectToMinio $scheme + +{{ if .Values.customCommands }} +# Run custom commands +{{- range .Values.customCommands }} +runCommand {{ .command }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/_helper_policy.tpl b/charts/mayastor/charts/loki/charts/minio/templates/_helper_policy.tpl new file mode 100644 index 0000000..8be998e --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/_helper_policy.tpl @@ -0,0 +1,28 @@ +{{- $statements_length := len .statements -}} +{{- $statements_length := sub $statements_length 1 -}} +{ + "Version": "2012-10-17", + "Statement": [ +{{- range $i, $statement := .statements }} + { + "Effect": "{{ $statement.effect | default "Allow" }}", + "Action": [ +"{{ $statement.actions | join "\",\n\"" }}" + ]{{ if $statement.resources }}, + "Resource": [ +"{{ $statement.resources | join "\",\n\"" }}" + ]{{ end }} +{{- if $statement.conditions }} +{{- $condition_len := len $statement.conditions }} +{{- $condition_len := sub $condition_len 1 }} + , + "Condition": { + {{- range $k,$v := $statement.conditions }} + {{- range $operator,$object := $v }} + "{{ $operator }}": { {{ $object }} }{{- if lt $k $condition_len }},{{- end }} + {{- end }}{{- end }} + }{{- end }} + }{{ if lt $i $statements_length }},{{end }} +{{- end }} + ] +} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/_helpers.tpl b/charts/mayastor/charts/loki/charts/minio/templates/_helpers.tpl new file mode 100644 index 0000000..1cb209e --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/_helpers.tpl @@ -0,0 +1,218 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "minio.name" -}} + {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +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 "minio.fullname" -}} + {{- if .Values.fullnameOverride -}} + {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- $name := default .Chart.Name .Values.nameOverride -}} + {{- if contains $name .Release.Name -}} + {{- .Release.Name | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "minio.chart" -}} + {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "minio.networkPolicy.apiVersion" -}} + {{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.Version -}} + {{- print "extensions/v1beta1" -}} + {{- else if semverCompare ">=1.7-0, <1.16-0" .Capabilities.KubeVersion.Version -}} + {{- print "networking.k8s.io/v1beta1" -}} + {{- else if semverCompare "^1.16-0" .Capabilities.KubeVersion.Version -}} + {{- print "networking.k8s.io/v1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for deployment. +*/}} +{{- define "minio.deployment.apiVersion" -}} + {{- if semverCompare "<1.9-0" .Capabilities.KubeVersion.Version -}} + {{- print "apps/v1beta2" -}} + {{- else -}} + {{- print "apps/v1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for statefulset. +*/}} +{{- define "minio.statefulset.apiVersion" -}} + {{- if semverCompare "<1.16-0" .Capabilities.KubeVersion.Version -}} + {{- print "apps/v1beta2" -}} + {{- else -}} + {{- print "apps/v1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "minio.ingress.apiVersion" -}} + {{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} + {{- print "extensions/v1beta1" -}} + {{- else if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion -}} + {{- print "networking.k8s.io/v1beta1" -}} + {{- else -}} + {{- print "networking.k8s.io/v1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for console ingress. +*/}} +{{- define "minio.consoleIngress.apiVersion" -}} + {{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}} + {{- print "extensions/v1beta1" -}} + {{- else if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion -}} + {{- print "networking.k8s.io/v1beta1" -}} + {{- else -}} + {{- print "networking.k8s.io/v1" -}} + {{- end -}} +{{- end -}} + +{{/* +Determine secret name. +*/}} +{{- define "minio.secretName" -}} + {{- if .Values.existingSecret -}} + {{- .Values.existingSecret }} + {{- else -}} + {{- include "minio.fullname" . -}} + {{- end -}} +{{- end -}} + +{{/* +Determine name for scc role and rolebinding +*/}} +{{- define "minio.sccRoleName" -}} + {{- printf "%s-%s" "scc" (include "minio.fullname" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Properly format optional additional arguments to MinIO binary +*/}} +{{- define "minio.extraArgs" -}} +{{- range .Values.extraArgs -}} +{{ " " }}{{ . }} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "minio.imagePullSecrets" -}} +{{/* +Helm 2.11 supports the assignment of a value to a variable defined in a different scope, +but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic. +Also, we can not use a single if because lazy evaluation is not an option +*/}} +{{- if .Values.global }} +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.global.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- else if .Values.imagePullSecrets }} +imagePullSecrets: + {{ toYaml .Values.imagePullSecrets }} +{{- end -}} +{{- else if .Values.imagePullSecrets }} +imagePullSecrets: + {{ toYaml .Values.imagePullSecrets }} +{{- end -}} +{{- end -}} + +{{/* +Formats volumeMount for MinIO TLS keys and trusted certs +*/}} +{{- define "minio.tlsKeysVolumeMount" -}} +{{- if .Values.tls.enabled }} +- name: cert-secret-volume + mountPath: {{ .Values.certsPath }} +{{- end }} +{{- if or .Values.tls.enabled (ne .Values.trustedCertsSecret "") }} +{{- $casPath := printf "%s/CAs" .Values.certsPath | clean }} +- name: trusted-cert-secret-volume + mountPath: {{ $casPath }} +{{- end }} +{{- end -}} + +{{/* +Formats volume for MinIO TLS keys and trusted certs +*/}} +{{- define "minio.tlsKeysVolume" -}} +{{- if .Values.tls.enabled }} +- name: cert-secret-volume + secret: + secretName: {{ tpl .Values.tls.certSecret $ }} + items: + - key: {{ .Values.tls.publicCrt }} + path: public.crt + - key: {{ .Values.tls.privateKey }} + path: private.key +{{- end }} +{{- if or .Values.tls.enabled (ne .Values.trustedCertsSecret "") }} +{{- $certSecret := eq .Values.trustedCertsSecret "" | ternary .Values.tls.certSecret .Values.trustedCertsSecret }} +{{- $publicCrt := eq .Values.trustedCertsSecret "" | ternary .Values.tls.publicCrt "" }} +- name: trusted-cert-secret-volume + secret: + secretName: {{ $certSecret }} + {{- if ne $publicCrt "" }} + items: + - key: {{ $publicCrt }} + path: public.crt + {{- end }} +{{- end }} +{{- end -}} + +{{/* +Returns the available value for certain key in an existing secret (if it exists), +otherwise it generates a random value. +*/}} +{{- define "minio.getValueFromSecret" }} + {{- $len := (default 16 .Length) | int -}} + {{- $obj := (lookup "v1" "Secret" .Namespace .Name).data -}} + {{- if $obj }} + {{- index $obj .Key | b64dec -}} + {{- else -}} + {{- randAlphaNum $len -}} + {{- end -}} +{{- end }} + +{{- define "minio.root.username" -}} + {{- if .Values.rootUser }} + {{- .Values.rootUser | toString }} + {{- else }} + {{- include "minio.getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "minio.fullname" .) "Length" 20 "Key" "rootUser") }} + {{- end }} +{{- end -}} + +{{- define "minio.root.password" -}} + {{- if .Values.rootPassword }} + {{- .Values.rootPassword | toString }} + {{- else }} + {{- include "minio.getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "minio.fullname" .) "Length" 40 "Key" "rootPassword") }} + {{- end }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/ciliumnetworkpolicy.yaml b/charts/mayastor/charts/loki/charts/minio/templates/ciliumnetworkpolicy.yaml new file mode 100644 index 0000000..1dc91bc --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/ciliumnetworkpolicy.yaml @@ -0,0 +1,33 @@ +{{- if and (.Values.networkPolicy.enabled) (eq .Values.networkPolicy.flavor "cilium") }} +kind: CiliumNetworkPolicy +apiVersion: cilium.io/v2 +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + endpointSelector: + matchLabels: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} + ingress: + - toPorts: + - ports: + - port: "{{ .Values.minioAPIPort }}" + protocol: TCP + - port: "{{ .Values.minioConsolePort }}" + protocol: TCP + {{- if not .Values.networkPolicy.allowExternal }} + fromEndpoints: + - matchLabels: + {{ template "minio.name" . }}-client: "true" + {{- end }} + egress: + {{- range $entity := .Values.networkPolicy.egressEntities }} + - toEntities: + - {{ $entity }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/configmap.yaml b/charts/mayastor/charts/loki/charts/minio/templates/configmap.yaml new file mode 100644 index 0000000..47f64cc --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/configmap.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + initialize: |- + {{- include (print $.Template.BasePath "/_helper_create_bucket.txt") . | nindent 4 }} + add-user: |- + {{- include (print $.Template.BasePath "/_helper_create_user.txt") . | nindent 4 }} + add-policy: |- + {{- include (print $.Template.BasePath "/_helper_create_policy.txt") . | nindent 4 }} + {{- range $idx, $policy := .Values.policies }} + # Policy: {{ $policy.name }} + policy_{{ $idx }}.json: |- + {{- include (print $.Template.BasePath "/_helper_policy.tpl") . | nindent 4 }} + {{ end }} + {{- range $idx, $svc := .Values.svcaccts }} + {{- if $svc.policy }} + # SVC: {{ $svc.accessKey }} + svc_policy_{{ $idx }}.json: |- + {{- include (print $.Template.BasePath "/_helper_policy.tpl") .policy | nindent 4 }} + {{- end }} + {{- end }} + add-svcacct: |- + {{- include (print $.Template.BasePath "/_helper_create_svcacct.txt") . | nindent 4 }} + custom-command: |- + {{- include (print $.Template.BasePath "/_helper_custom_command.txt") . | nindent 4 }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/console-ingress.yaml b/charts/mayastor/charts/loki/charts/minio/templates/console-ingress.yaml new file mode 100644 index 0000000..79a2b1b --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/console-ingress.yaml @@ -0,0 +1,55 @@ +{{- if .Values.consoleIngress.enabled -}} +{{- $fullName := printf "%s-console" (include "minio.fullname" .) -}} +{{- $servicePort := .Values.consoleService.port -}} +{{- $ingressPath := .Values.consoleIngress.path -}} +apiVersion: {{ template "minio.consoleIngress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.consoleIngress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.consoleIngress.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.consoleIngress.ingressClassName }} + ingressClassName: {{ .Values.consoleIngress.ingressClassName }} + {{- end }} + {{- if .Values.consoleIngress.tls }} + tls: + {{- range .Values.consoleIngress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.consoleIngress.hosts }} + - http: + paths: + - path: {{ $ingressPath }} + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + pathType: Prefix + backend: + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + backend: + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- if . }} + host: {{ tpl . $ | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/console-service.yaml b/charts/mayastor/charts/loki/charts/minio/templates/console-service.yaml new file mode 100644 index 0000000..f09e3f3 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/console-service.yaml @@ -0,0 +1,45 @@ +{{ $scheme := .Values.tls.enabled | ternary "https" "http" }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "minio.fullname" . }}-console + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.consoleService.annotations }} + annotations: {{- toYaml .Values.consoleService.annotations | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.consoleService.type }} + {{- if and (eq .Values.consoleService.type "ClusterIP") .Values.consoleService.clusterIP }} + clusterIP: {{ .Values.consoleService.clusterIP }} + {{- end }} + {{- if or (eq .Values.consoleService.type "LoadBalancer") (eq .Values.consoleService.type "NodePort") }} + externalTrafficPolicy: {{ .Values.consoleService.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.consoleService.type "LoadBalancer") .Values.consoleService.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ .Values.consoleService.loadBalancerSourceRanges }} + {{ end }} + {{- if and (eq .Values.consoleService.type "LoadBalancer") (not (empty .Values.consoleService.loadBalancerIP)) }} + loadBalancerIP: {{ .Values.consoleService.loadBalancerIP }} + {{- end }} + ports: + - name: {{ $scheme }} + port: {{ .Values.consoleService.port }} + protocol: TCP + {{- if (and (eq .Values.consoleService.type "NodePort") ( .Values.consoleService.nodePort)) }} + nodePort: {{ .Values.consoleService.nodePort }} + {{- else }} + targetPort: {{ .Values.minioConsolePort }} + {{- end }} + {{- if .Values.consoleService.externalIPs }} + externalIPs: + {{- range $i , $ip := .Values.consoleService.externalIPs }} + - {{ $ip }} + {{- end }} + {{- end }} + selector: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/deployment.yaml b/charts/mayastor/charts/loki/charts/minio/templates/deployment.yaml new file mode 100644 index 0000000..4c57010 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/deployment.yaml @@ -0,0 +1,213 @@ +{{- if eq .Values.mode "standalone" }} +{{ $scheme := .Values.tls.enabled | ternary "https" "http" }} +{{ $bucketRoot := or ($.Values.bucketRoot) ($.Values.mountPath) }} +apiVersion: {{ template "minio.deployment.apiVersion" . }} +kind: Deployment +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.additionalLabels }} + {{- toYaml .Values.additionalLabels | nindent 4 }} + {{- end }} + {{- if .Values.additionalAnnotations }} + annotations: {{- toYaml .Values.additionalAnnotations | nindent 4 }} + {{- end }} +spec: + strategy: + type: {{ .Values.deploymentUpdate.type }} + {{- if eq .Values.deploymentUpdate.type "RollingUpdate" }} + rollingUpdate: + maxSurge: {{ .Values.deploymentUpdate.maxSurge }} + maxUnavailable: {{ .Values.deploymentUpdate.maxUnavailable }} + {{- end }} + replicas: 1 + selector: + matchLabels: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} + template: + metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} + {{- if .Values.podLabels }} + {{- toYaml .Values.podLabels | nindent 8 }} + {{- end }} + annotations: + {{- if not .Values.ignoreChartChecksums }} + checksum/secrets: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }} + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.podAnnotations }} + {{- toYaml .Values.podAnnotations | trimSuffix "\n" | nindent 8 }} + {{- end }} + spec: + {{- if .Values.priorityClassName }} + priorityClassName: "{{ .Values.priorityClassName }}" + {{- end }} + {{- if .Values.runtimeClassName }} + runtimeClassName: "{{ .Values.runtimeClassName }}" + {{- end }} + {{- if and .Values.securityContext.enabled .Values.persistence.enabled }} + securityContext: + {{ omit .Values.securityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{ if .Values.serviceAccount.create }} + serviceAccountName: {{ .Values.serviceAccount.name }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - "/bin/sh" + - "-ce" + - "/usr/bin/docker-entrypoint.sh minio server {{ $bucketRoot }} -S {{ .Values.certsPath }} --address :{{ .Values.minioAPIPort }} --console-address :{{ .Values.minioConsolePort }} {{- template "minio.extraArgs" . }}" + volumeMounts: + - name: minio-user + mountPath: "/tmp/credentials" + readOnly: true + - name: export + mountPath: {{ .Values.mountPath }} + {{- if and .Values.persistence.enabled .Values.persistence.subPath }} + subPath: "{{ .Values.persistence.subPath }}" + {{- end }} + {{- if .Values.extraSecret }} + - name: extra-secret + mountPath: "/tmp/minio-config-env" + {{- end }} + {{- include "minio.tlsKeysVolumeMount" . | indent 12 }} + {{- if .Values.extraVolumeMounts }} + {{- toYaml .Values.extraVolumeMounts | nindent 12 }} + {{- end }} + ports: + - name: {{ $scheme }} + containerPort: {{ .Values.minioAPIPort }} + - name: {{ $scheme }}-console + containerPort: {{ .Values.minioConsolePort }} + env: + - name: MINIO_ROOT_USER + valueFrom: + secretKeyRef: + name: {{ template "minio.secretName" . }} + key: rootUser + - name: MINIO_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "minio.secretName" . }} + key: rootPassword + {{- if .Values.extraSecret }} + - name: MINIO_CONFIG_ENV_FILE + value: "/tmp/minio-config-env/config.env" + {{- end }} + {{- if .Values.metrics.serviceMonitor.public }} + - name: MINIO_PROMETHEUS_AUTH_TYPE + value: "public" + {{- end }} + {{- if .Values.oidc.enabled }} + - name: MINIO_IDENTITY_OPENID_CONFIG_URL + value: {{ .Values.oidc.configUrl }} + - name: MINIO_IDENTITY_OPENID_CLIENT_ID + {{- if and .Values.oidc.existingClientSecretName .Values.oidc.existingClientIdKey }} + valueFrom: + secretKeyRef: + name: {{ .Values.oidc.existingClientSecretName }} + key: {{ .Values.oidc.existingClientIdKey }} + {{- else }} + value: {{ .Values.oidc.clientId }} + {{- end }} + - name: MINIO_IDENTITY_OPENID_CLIENT_SECRET + {{- if and .Values.oidc.existingClientSecretName .Values.oidc.existingClientSecretKey }} + valueFrom: + secretKeyRef: + name: {{ .Values.oidc.existingClientSecretName }} + key: {{ .Values.oidc.existingClientSecretKey }} + {{- else }} + value: {{ .Values.oidc.clientSecret }} + {{- end }} + - name: MINIO_IDENTITY_OPENID_CLAIM_NAME + value: {{ .Values.oidc.claimName }} + - name: MINIO_IDENTITY_OPENID_CLAIM_PREFIX + value: {{ .Values.oidc.claimPrefix }} + - name: MINIO_IDENTITY_OPENID_SCOPES + value: {{ .Values.oidc.scopes }} + - name: MINIO_IDENTITY_OPENID_COMMENT + value: {{ .Values.oidc.comment }} + - name: MINIO_IDENTITY_OPENID_REDIRECT_URI + value: {{ .Values.oidc.redirectUri }} + - name: MINIO_IDENTITY_OPENID_DISPLAY_NAME + value: {{ .Values.oidc.displayName }} + {{- end }} + {{- if .Values.etcd.endpoints }} + - name: MINIO_ETCD_ENDPOINTS + value: {{ join "," .Values.etcd.endpoints | quote }} + {{- if .Values.etcd.clientCert }} + - name: MINIO_ETCD_CLIENT_CERT + value: "/tmp/credentials/etcd_client_cert.pem" + {{- end }} + {{- if .Values.etcd.clientCertKey }} + - name: MINIO_ETCD_CLIENT_CERT_KEY + value: "/tmp/credentials/etcd_client_cert_key.pem" + {{- end }} + {{- if .Values.etcd.pathPrefix }} + - name: MINIO_ETCD_PATH_PREFIX + value: {{ .Values.etcd.pathPrefix }} + {{- end }} + {{- if .Values.etcd.corednsPathPrefix }} + - name: MINIO_ETCD_COREDNS_PATH + value: {{ .Values.etcd.corednsPathPrefix }} + {{- end }} + {{- end }} + {{- range $key, $val := .Values.environment }} + - name: {{ $key }} + value: {{ tpl $val $ | quote }} + {{- end }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- if and .Values.securityContext.enabled .Values.persistence.enabled }} + {{- with .Values.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12}} + {{- end }} + {{- end }} + {{- with .Values.extraContainers }} + {{- if eq (typeOf .) "string" }} + {{- tpl . $ | nindent 8 }} + {{- else }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "minio.imagePullSecrets" . | indent 6 }} + {{- with .Values.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: export + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim | default (include "minio.fullname" .) }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.extraSecret }} + - name: extra-secret + secret: + secretName: {{ .Values.extraSecret }} + {{- end }} + - name: minio-user + secret: + secretName: {{ template "minio.secretName" . }} + {{- include "minio.tlsKeysVolume" . | indent 8 }} + {{- if .Values.extraVolumes }} + {{ toYaml .Values.extraVolumes | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/ingress.yaml b/charts/mayastor/charts/loki/charts/minio/templates/ingress.yaml new file mode 100644 index 0000000..1a564c6 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/ingress.yaml @@ -0,0 +1,55 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "minio.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +{{- $ingressPath := .Values.ingress.path -}} +apiVersion: {{ template "minio.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingress.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - http: + paths: + - path: {{ $ingressPath }} + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + pathType: Prefix + backend: + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + backend: + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- if . }} + host: {{ tpl . $ | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/networkpolicy.yaml b/charts/mayastor/charts/loki/charts/minio/templates/networkpolicy.yaml new file mode 100644 index 0000000..b9c0771 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/networkpolicy.yaml @@ -0,0 +1,26 @@ +{{- if and (.Values.networkPolicy.enabled) (eq .Values.networkPolicy.flavor "kubernetes") }} +kind: NetworkPolicy +apiVersion: {{ template "minio.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + podSelector: + matchLabels: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} + ingress: + - ports: + - port: {{ .Values.minioAPIPort }} + - port: {{ .Values.minioConsolePort }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ template "minio.name" . }}-client: "true" + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/poddisruptionbudget.yaml b/charts/mayastor/charts/loki/charts/minio/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000..a5f90a0 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/poddisruptionbudget.yaml @@ -0,0 +1,17 @@ +{{- if .Values.podDisruptionBudget.enabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1beta1/PodDisruptionBudget" }} +apiVersion: policy/v1beta1 +{{- else }} +apiVersion: policy/v1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: minio + labels: + app: {{ template "minio.name" . }} +spec: + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + app: {{ template "minio.name" . }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/post-job.yaml b/charts/mayastor/charts/loki/charts/minio/templates/post-job.yaml new file mode 100644 index 0000000..955d655 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/post-job.yaml @@ -0,0 +1,258 @@ +{{- if or .Values.buckets .Values.users .Values.policies .Values.customCommands .Values.svcaccts }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "minio.fullname" . }}-post-job + labels: + app: {{ template "minio.name" . }}-post-job + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation + {{- with .Values.postJob.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + template: + metadata: + labels: + app: {{ template "minio.name" . }}-job + release: {{ .Release.Name }} + {{- if .Values.podLabels }} + {{- toYaml .Values.podLabels | nindent 8 }} + {{- end }} + {{- if .Values.postJob.podAnnotations }} + annotations: {{- toYaml .Values.postJob.podAnnotations | nindent 8 }} + {{- end }} + spec: + restartPolicy: OnFailure + {{- include "minio.imagePullSecrets" . | indent 6 }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.postJob.nodeSelector | nindent 8 }} + {{- end }} + {{- with .Values.postJob.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.postJob.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.postJob.securityContext.enabled }} + securityContext: {{ omit .Values.postJob.securityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + volumes: + - name: etc-path + emptyDir: {} + - name: tmp + emptyDir: {} + - name: minio-configuration + projected: + sources: + - configMap: + name: {{ template "minio.fullname" . }} + - secret: + name: {{ template "minio.secretName" . }} + {{- range (concat .Values.users (default (list) .Values.svcaccts)) }} + {{- if .existingSecret }} + - secret: + name: {{ tpl .existingSecret $ }} + items: + - key: {{ .existingSecretKey }} + path: secrets/{{ tpl .existingSecret $ }}/{{ tpl .existingSecretKey $ }} + {{- end }} + {{- end }} + {{- range ( default list .Values.svcaccts ) }} + {{- if .existingSecret }} + - secret: + name: {{ tpl .existingSecret $ }} + items: + - key: {{ .existingSecretKey }} + path: secrets-svc/{{ tpl .existingSecret $ }}/{{ tpl .existingSecretKey $ }} + {{- end }} + {{- end }} + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + secret: + secretName: {{ .Values.tls.certSecret }} + items: + - key: {{ .Values.tls.publicCrt }} + path: CAs/public.crt + {{- end }} + {{- if .Values.customCommandJob.extraVolumes }} + {{- toYaml .Values.customCommandJob.extraVolumes | nindent 8 }} + {{- end }} + {{- if .Values.serviceAccount.create }} + serviceAccountName: {{ .Values.serviceAccount.name }} + {{- end }} + {{- if .Values.policies }} + initContainers: + - name: minio-make-policy + image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}" + {{- if .Values.makePolicyJob.securityContext.enabled }} + {{- with .Values.makePolicyJob.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.mcImage.pullPolicy }} + {{- if .Values.makePolicyJob.exitCommand }} + command: [ "/bin/sh", "-c" ] + args: [ "/bin/sh /config/add-policy; EV=$?; {{ .Values.makePolicyJob.exitCommand }} && exit $EV" ] + {{- else }} + command: [ "/bin/sh", "/config/add-policy" ] + {{- end }} + env: + - name: MINIO_ENDPOINT + value: {{ template "minio.fullname" . }} + - name: MINIO_PORT + value: {{ .Values.service.port | quote }} + volumeMounts: + - name: etc-path + mountPath: /etc/minio/mc + - name: tmp + mountPath: /tmp + - name: minio-configuration + mountPath: /config + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + mountPath: {{ .Values.configPathmc }}certs + {{- end }} + resources: {{- toYaml .Values.makePolicyJob.resources | nindent 12 }} + {{- end }} + containers: + {{- if .Values.buckets }} + - name: minio-make-bucket + image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}" + {{- if .Values.makeBucketJob.securityContext.enabled }} + {{- with .Values.makeBucketJob.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.mcImage.pullPolicy }} + {{- if .Values.makeBucketJob.exitCommand }} + command: [ "/bin/sh", "-c" ] + args: [ "/bin/sh /config/initialize; EV=$?; {{ .Values.makeBucketJob.exitCommand }} && exit $EV" ] + {{- else }} + command: [ "/bin/sh", "/config/initialize" ] + {{- end }} + env: + - name: MINIO_ENDPOINT + value: {{ template "minio.fullname" . }} + - name: MINIO_PORT + value: {{ .Values.service.port | quote }} + volumeMounts: + - name: etc-path + mountPath: /etc/minio/mc + - name: tmp + mountPath: /tmp + - name: minio-configuration + mountPath: /config + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + mountPath: {{ .Values.configPathmc }}certs + {{- end }} + resources: {{- toYaml .Values.makeBucketJob.resources | nindent 12 }} + {{- end }} + {{- if .Values.users }} + - name: minio-make-user + image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}" + {{- if .Values.makeUserJob.securityContext.enabled }} + {{- with .Values.makeUserJob.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.mcImage.pullPolicy }} + {{- if .Values.makeUserJob.exitCommand }} + command: [ "/bin/sh", "-c" ] + args: [ "/bin/sh /config/add-user; EV=$?; {{ .Values.makeUserJob.exitCommand }} && exit $EV" ] + {{- else }} + command: [ "/bin/sh", "/config/add-user" ] + {{- end }} + env: + - name: MINIO_ENDPOINT + value: {{ template "minio.fullname" . }} + - name: MINIO_PORT + value: {{ .Values.service.port | quote }} + volumeMounts: + - name: etc-path + mountPath: /etc/minio/mc + - name: tmp + mountPath: /tmp + - name: minio-configuration + mountPath: /config + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + mountPath: {{ .Values.configPathmc }}certs + {{- end }} + resources: {{- toYaml .Values.makeUserJob.resources | nindent 12 }} + {{- end }} + {{- if .Values.customCommands }} + - name: minio-custom-command + image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}" + {{- if .Values.customCommandJob.securityContext.enabled }} + {{- with .Values.customCommandJob.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.mcImage.pullPolicy }} + {{- if .Values.customCommandJob.exitCommand }} + command: [ "/bin/sh", "-c" ] + args: [ "/bin/sh /config/custom-command; EV=$?; {{ .Values.customCommandJob.exitCommand }} && exit $EV" ] + {{- else }} + command: [ "/bin/sh", "/config/custom-command" ] + {{- end }} + env: + - name: MINIO_ENDPOINT + value: {{ template "minio.fullname" . }} + - name: MINIO_PORT + value: {{ .Values.service.port | quote }} + volumeMounts: + - name: etc-path + mountPath: /etc/minio/mc + - name: tmp + mountPath: /tmp + - name: minio-configuration + mountPath: /config + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + mountPath: {{ .Values.configPathmc }}certs + {{- end }} + {{- if .Values.customCommandJob.extraVolumeMounts }} + {{- toYaml .Values.customCommandJob.extraVolumeMounts | nindent 12 }} + {{- end }} + resources: {{- toYaml .Values.customCommandJob.resources | nindent 12 }} + {{- end }} + {{- if .Values.svcaccts }} + - name: minio-make-svcacct + image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}" + {{- if .Values.makeServiceAccountJob.securityContext.enabled }} + {{- with .Values.makeServiceAccountJob.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12 }} + {{- end }} + {{- end }} + imagePullPolicy: {{ .Values.mcImage.pullPolicy }} + {{- if .Values.makeServiceAccountJob.exitCommand }} + command: [ "/bin/sh", "-c" ] + args: ["/bin/sh /config/add-svcacct; EV=$?; {{ .Values.makeServiceAccountJob.exitCommand }} && exit $EV" ] + {{- else }} + command: ["/bin/sh", "/config/add-svcacct"] + {{- end }} + env: + - name: MINIO_ENDPOINT + value: {{ template "minio.fullname" . }} + - name: MINIO_PORT + value: {{ .Values.service.port | quote }} + volumeMounts: + - name: etc-path + mountPath: /etc/minio/mc + - name: tmp + mountPath: /tmp + - name: minio-configuration + mountPath: /config + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + mountPath: {{ .Values.configPathmc }}certs + {{- end }} + resources: {{- toYaml .Values.makeServiceAccountJob.resources | nindent 12 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/pvc.yaml b/charts/mayastor/charts/loki/charts/minio/templates/pvc.yaml new file mode 100644 index 0000000..60f5267 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/pvc.yaml @@ -0,0 +1,32 @@ +{{- if eq .Values.mode "standalone" }} +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.persistence.annotations }} + annotations: {{- toYaml .Values.persistence.annotations | nindent 4 }} + {{- end }} +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{- if .Values.persistence.storageClass }} + {{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" + {{- end }} + {{- end }} + {{- if .Values.persistence.volumeName }} + volumeName: "{{ .Values.persistence.volumeName }}" + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/secrets.yaml b/charts/mayastor/charts/loki/charts/minio/templates/secrets.yaml new file mode 100644 index 0000000..476c3da --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/secrets.yaml @@ -0,0 +1,21 @@ +{{- if not .Values.existingSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "minio.secretName" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +data: + rootUser: {{ include "minio.root.username" . | b64enc | quote }} + rootPassword: {{ include "minio.root.password" . | b64enc | quote }} + {{- if .Values.etcd.clientCert }} + etcd_client.crt: {{ .Values.etcd.clientCert | toString | b64enc | quote }} + {{- end }} + {{- if .Values.etcd.clientCertKey }} + etcd_client.key: {{ .Values.etcd.clientCertKey | toString | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/securitycontextconstraints.yaml b/charts/mayastor/charts/loki/charts/minio/templates/securitycontextconstraints.yaml new file mode 100644 index 0000000..4bac7e3 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/securitycontextconstraints.yaml @@ -0,0 +1,45 @@ +{{- if and .Values.securityContext.enabled .Values.persistence.enabled (.Capabilities.APIVersions.Has "security.openshift.io/v1") }} +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +allowHostDirVolumePlugin: false +allowHostIPC: false +allowHostNetwork: false +allowHostPID: false +allowHostPorts: false +allowPrivilegeEscalation: true +allowPrivilegedContainer: false +allowedCapabilities: [] +readOnlyRootFilesystem: false +defaultAddCapabilities: [] +requiredDropCapabilities: +- KILL +- MKNOD +- SETUID +- SETGID +fsGroup: + type: MustRunAs + ranges: + - max: {{ .Values.securityContext.fsGroup }} + min: {{ .Values.securityContext.fsGroup }} +runAsUser: + type: MustRunAs + uid: {{ .Values.securityContext.runAsUser }} +seLinuxContext: + type: MustRunAs +supplementalGroups: + type: RunAsAny +volumes: +- configMap +- downwardAPI +- emptyDir +- persistentVolumeClaim +- projected +- secret +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/service.yaml b/charts/mayastor/charts/loki/charts/minio/templates/service.yaml new file mode 100644 index 0000000..d872cd0 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/service.yaml @@ -0,0 +1,46 @@ +{{ $scheme := .Values.tls.enabled | ternary "https" "http" }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + monitoring: "true" + {{- if .Values.service.annotations }} + annotations: {{- toYaml .Values.service.annotations | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- if and (eq .Values.service.type "ClusterIP") .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + {{- if or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort") }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ .Values.service.loadBalancerSourceRanges }} + {{ end }} + {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP)) }} + loadBalancerIP: {{ default "" .Values.service.loadBalancerIP | quote }} + {{- end }} + ports: + - name: {{ $scheme }} + port: {{ .Values.service.port }} + protocol: TCP + {{- if (and (eq .Values.service.type "NodePort") ( .Values.service.nodePort)) }} + nodePort: {{ .Values.service.nodePort }} + {{- else }} + targetPort: {{ .Values.minioAPIPort }} + {{- end }} + {{- if .Values.service.externalIPs }} + externalIPs: + {{- range $i , $ip := .Values.service.externalIPs }} + - {{ $ip }} + {{- end }} + {{- end }} + selector: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/serviceaccount.yaml b/charts/mayastor/charts/loki/charts/minio/templates/serviceaccount.yaml new file mode 100644 index 0000000..0784015 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/serviceaccount.yaml @@ -0,0 +1,6 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.name | quote }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/servicemonitor.yaml b/charts/mayastor/charts/loki/charts/minio/templates/servicemonitor.yaml new file mode 100644 index 0000000..f875a85 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/servicemonitor.yaml @@ -0,0 +1,112 @@ +{{- if and .Values.metrics.serviceMonitor.enabled .Values.metrics.serviceMonitor.includeNode }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "minio.fullname" . }} + {{- if .Values.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.metrics.serviceMonitor.namespace }} + {{- end }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.metrics.serviceMonitor.additionalLabels }} + {{- toYaml .Values.metrics.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.annotations }} + annotations: {{- toYaml .Values.metrics.serviceMonitor.annotations | nindent 4 }} + {{- end }} +spec: + endpoints: + {{- if .Values.tls.enabled }} + - port: https + scheme: https + tlsConfig: + ca: + secret: + name: {{ .Values.tls.certSecret }} + key: {{ .Values.tls.publicCrt }} + serverName: {{ template "minio.fullname" . }} + {{- else }} + - port: http + scheme: http + {{- end }} + path: /minio/v2/metrics/node + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelConfigs }} + {{- toYaml .Values.metrics.serviceMonitor.relabelConfigs | nindent 6 }} + {{- end }} + {{- if not .Values.metrics.serviceMonitor.public }} + bearerTokenSecret: + name: {{ template "minio.fullname" . }}-prometheus + key: token + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} + selector: + matchLabels: + app: {{ include "minio.name" . }} + release: {{ .Release.Name }} + monitoring: "true" +{{- end }} +{{- if .Values.metrics.serviceMonitor.enabled }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: Probe +metadata: + name: {{ template "minio.fullname" . }}-cluster + {{- if .Values.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.metrics.serviceMonitor.namespace }} + {{- end }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.metrics.serviceMonitor.additionalLabels }} + {{- toYaml .Values.metrics.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} +spec: + jobName: {{ template "minio.fullname" . }} + {{- if .Values.tls.enabled }} + tlsConfig: + ca: + secret: + name: {{ .Values.tls.certSecret }} + key: {{ .Values.tls.publicCrt }} + serverName: {{ template "minio.fullname" . }} + {{- end }} + prober: + url: {{ template "minio.fullname" . }}.{{ .Release.Namespace }}:{{ .Values.service.port }} + path: /minio/v2/metrics/cluster + {{- if .Values.tls.enabled }} + scheme: https + {{- else }} + scheme: http + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelConfigsCluster }} + {{- toYaml .Values.metrics.serviceMonitor.relabelConfigsCluster | nindent 2 }} + {{- end }} + targets: + staticConfig: + static: + - {{ template "minio.fullname" . }}.{{ .Release.Namespace }} + {{- if not .Values.metrics.serviceMonitor.public }} + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + bearerTokenSecret: + name: {{ template "minio.fullname" . }}-prometheus + key: token + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/templates/statefulset.yaml b/charts/mayastor/charts/loki/charts/minio/templates/statefulset.yaml new file mode 100644 index 0000000..d671eaa --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/templates/statefulset.yaml @@ -0,0 +1,267 @@ +{{- if eq .Values.mode "distributed" }} +{{ $poolCount := .Values.pools | int }} +{{ $nodeCount := .Values.replicas | int }} +{{ $replicas := mul $poolCount $nodeCount }} +{{ $drivesPerNode := .Values.drivesPerNode | int }} +{{ $scheme := .Values.tls.enabled | ternary "https" "http" }} +{{ $mountPath := .Values.mountPath }} +{{ $bucketRoot := or ($.Values.bucketRoot) ($.Values.mountPath) }} +{{ $subPath := .Values.persistence.subPath }} +{{ $penabled := .Values.persistence.enabled }} +{{ $accessMode := .Values.persistence.accessMode }} +{{ $storageClass := .Values.persistence.storageClass }} +{{ $psize := .Values.persistence.size }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "minio.fullname" . }}-svc + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + publishNotReadyAddresses: true + clusterIP: None + ports: + - name: {{ $scheme }} + port: {{ .Values.service.port }} + protocol: TCP + targetPort: {{ .Values.minioAPIPort }} + selector: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} +--- +apiVersion: {{ template "minio.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.additionalLabels }} + {{- toYaml .Values.additionalLabels | nindent 4 }} + {{- end }} + {{- if .Values.additionalAnnotations }} + annotations: {{- toYaml .Values.additionalAnnotations | nindent 4 }} + {{- end }} +spec: + updateStrategy: + type: {{ .Values.statefulSetUpdate.updateStrategy }} + podManagementPolicy: "Parallel" + serviceName: {{ template "minio.fullname" . }}-svc + replicas: {{ $replicas }} + selector: + matchLabels: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} + template: + metadata: + name: {{ template "minio.fullname" . }} + labels: + app: {{ template "minio.name" . }} + release: {{ .Release.Name }} + {{- if .Values.podLabels }} + {{- toYaml .Values.podLabels | nindent 8 }} + {{- end }} + annotations: + {{- if not .Values.ignoreChartChecksums }} + checksum/secrets: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }} + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.podAnnotations }} + {{- toYaml .Values.podAnnotations | nindent 8 }} + {{- end }} + spec: + {{- if .Values.priorityClassName }} + priorityClassName: "{{ .Values.priorityClassName }}" + {{- end }} + {{- if .Values.runtimeClassName }} + runtimeClassName: "{{ .Values.runtimeClassName }}" + {{- end }} + {{- if and .Values.securityContext.enabled .Values.persistence.enabled }} + securityContext: + {{- omit .Values.securityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{- if .Values.serviceAccount.create }} + serviceAccountName: {{ .Values.serviceAccount.name }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: [ + "/bin/sh", + "-ce", + "/usr/bin/docker-entrypoint.sh minio server {{- range $i := until $poolCount }}{{ $factor := mul $i $nodeCount }}{{ $endIndex := add $factor $nodeCount }}{{ $beginIndex := mul $i $nodeCount }} {{ $scheme }}://{{ template `minio.fullname` $ }}-{{ `{` }}{{ $beginIndex }}...{{ sub $endIndex 1 }}{{ `}`}}.{{ template `minio.fullname` $ }}-svc.{{ $.Release.Namespace }}.svc{{if (gt $drivesPerNode 1)}}{{ $bucketRoot }}-{{ `{` }}0...{{ sub $drivesPerNode 1 }}{{ `}` }}{{ else }}{{ $bucketRoot }}{{end }}{{- end }} -S {{ .Values.certsPath }} --address :{{ .Values.minioAPIPort }} --console-address :{{ .Values.minioConsolePort }} {{- template `minio.extraArgs` . }}" + ] + volumeMounts: + {{- if $penabled }} + {{- if (gt $drivesPerNode 1) }} + {{- range $i := until $drivesPerNode }} + - name: export-{{ $i }} + mountPath: {{ $mountPath }}-{{ $i }} + {{- if and $penabled $subPath }} + subPath: {{ $subPath }} + {{- end }} + {{- end }} + {{- else }} + - name: export + mountPath: {{ $mountPath }} + {{- if and $penabled $subPath }} + subPath: {{ $subPath }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.extraSecret }} + - name: extra-secret + mountPath: "/tmp/minio-config-env" + {{- end }} + {{- include "minio.tlsKeysVolumeMount" . | indent 12 }} + {{- if .Values.extraVolumeMounts }} + {{- toYaml .Values.extraVolumeMounts | nindent 12 }} + {{- end }} + ports: + - name: {{ $scheme }} + containerPort: {{ .Values.minioAPIPort }} + - name: {{ $scheme }}-console + containerPort: {{ .Values.minioConsolePort }} + env: + - name: MINIO_ROOT_USER + valueFrom: + secretKeyRef: + name: {{ template "minio.secretName" . }} + key: rootUser + - name: MINIO_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "minio.secretName" . }} + key: rootPassword + {{- if .Values.extraSecret }} + - name: MINIO_CONFIG_ENV_FILE + value: "/tmp/minio-config-env/config.env" + {{- end }} + {{- if .Values.metrics.serviceMonitor.public }} + - name: MINIO_PROMETHEUS_AUTH_TYPE + value: "public" + {{- end }} + {{- if .Values.oidc.enabled }} + - name: MINIO_IDENTITY_OPENID_CONFIG_URL + value: {{ .Values.oidc.configUrl }} + - name: MINIO_IDENTITY_OPENID_CLIENT_ID + {{- if and .Values.oidc.existingClientSecretName .Values.oidc.existingClientIdKey }} + valueFrom: + secretKeyRef: + name: {{ .Values.oidc.existingClientSecretName }} + key: {{ .Values.oidc.existingClientIdKey }} + {{- else }} + value: {{ .Values.oidc.clientId }} + {{- end }} + - name: MINIO_IDENTITY_OPENID_CLIENT_SECRET + {{- if and .Values.oidc.existingClientSecretName .Values.oidc.existingClientSecretKey }} + valueFrom: + secretKeyRef: + name: {{ .Values.oidc.existingClientSecretName }} + key: {{ .Values.oidc.existingClientSecretKey }} + {{- else }} + value: {{ .Values.oidc.clientSecret }} + {{- end }} + - name: MINIO_IDENTITY_OPENID_CLAIM_NAME + value: {{ .Values.oidc.claimName }} + - name: MINIO_IDENTITY_OPENID_CLAIM_PREFIX + value: {{ .Values.oidc.claimPrefix }} + - name: MINIO_IDENTITY_OPENID_SCOPES + value: {{ .Values.oidc.scopes }} + - name: MINIO_IDENTITY_OPENID_COMMENT + value: {{ .Values.oidc.comment }} + - name: MINIO_IDENTITY_OPENID_REDIRECT_URI + value: {{ .Values.oidc.redirectUri }} + - name: MINIO_IDENTITY_OPENID_DISPLAY_NAME + value: {{ .Values.oidc.displayName }} + {{- end }} + {{- range $key, $val := .Values.environment }} + - name: {{ $key }} + value: {{ tpl $val $ | quote }} + {{- end }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- if and .Values.securityContext.enabled .Values.persistence.enabled }} + {{- with .Values.containerSecurityContext }} + securityContext: {{ toYaml . | nindent 12}} + {{- end }} + {{- end }} + {{- with .Values.extraContainers }} + {{- if eq (typeOf .) "string" }} + {{- tpl . $ | nindent 8 }} + {{- else }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "minio.imagePullSecrets" . | indent 6 }} + {{- with .Values.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: {{- toYaml . | nindent 8 }} + {{- end }} + {{- if and (gt $replicas 1) (ge .Capabilities.KubeVersion.Major "1") (ge .Capabilities.KubeVersion.Minor "19") }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + volumes: + - name: minio-user + secret: + secretName: {{ template "minio.secretName" . }} + {{- if .Values.extraSecret }} + - name: extra-secret + secret: + secretName: {{ .Values.extraSecret }} + {{- end }} + {{- include "minio.tlsKeysVolume" . | indent 8 }} + {{- if .Values.extraVolumes }} + {{- toYaml .Values.extraVolumes | nindent 8 }} + {{- end }} + {{- if .Values.persistence.enabled }} + volumeClaimTemplates: + {{- if gt $drivesPerNode 1 }} + {{- range $diskId := until $drivesPerNode}} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: export-{{ $diskId }} + {{- if $.Values.persistence.annotations }} + annotations: {{- toYaml $.Values.persistence.annotations | nindent 10 }} + {{- end }} + spec: + accessModes: [ {{ $accessMode | quote }} ] + {{- if $storageClass }} + storageClassName: {{ $storageClass }} + {{- end }} + resources: + requests: + storage: {{ $psize }} + {{- end }} + {{- else }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: export + {{- if $.Values.persistence.annotations }} + annotations: {{- toYaml $.Values.persistence.annotations | nindent 10 }} + {{- end }} + spec: + accessModes: [ {{ $accessMode | quote }} ] + {{- if $storageClass }} + storageClassName: {{ $storageClass }} + {{- end }} + resources: + requests: + storage: {{ $psize }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/minio/values.yaml b/charts/mayastor/charts/loki/charts/minio/values.yaml new file mode 100644 index 0000000..4c9714e --- /dev/null +++ b/charts/mayastor/charts/loki/charts/minio/values.yaml @@ -0,0 +1,593 @@ +## Provide a name in place of minio for `app:` labels +## +nameOverride: "" + +## Provide a name to substitute for the full names of resources +## +fullnameOverride: "" + +## set kubernetes cluster domain where minio is running +## +clusterDomain: cluster.local + +## Set default image, imageTag, and imagePullPolicy. mode is used to indicate the +## +image: + repository: quay.io/minio/minio + tag: RELEASE.2024-12-18T13-15-44Z + pullPolicy: IfNotPresent + +imagePullSecrets: [] +# - name: "image-pull-secret" + +## Set default image, imageTag, and imagePullPolicy for the `mc` (the minio +## client used to create a default bucket). +## +mcImage: + repository: quay.io/minio/mc + tag: RELEASE.2024-11-21T17-21-54Z + pullPolicy: IfNotPresent + +## minio mode, i.e. standalone or distributed +mode: distributed ## other supported values are "standalone" + +## Additional labels to include with deployment or statefulset +additionalLabels: {} + +## Additional annotations to include with deployment or statefulset +additionalAnnotations: {} + +## Typically the deployment/statefulset includes checksums of secrets/config, +## So that when these change on a subsequent helm install, the deployment/statefulset +## is restarted. This can result in unnecessary restarts under GitOps tooling such as +## flux, so set to "true" to disable this behaviour. +ignoreChartChecksums: false + +## Additional arguments to pass to minio binary +extraArgs: [] +# example for enabling FTP: +# - --ftp=\"address=:8021\" +# - --ftp=\"passive-port-range=10000-10010\" + +## Additional volumes to minio container +extraVolumes: [] + +## Additional volumeMounts to minio container +extraVolumeMounts: [] + +## Additional sidecar containers +extraContainers: [] + +## Internal port number for MinIO S3 API container +## Change service.port to change external port number +minioAPIPort: "9000" + +## Internal port number for MinIO Browser Console container +## Change consoleService.port to change external port number +minioConsolePort: "9001" + +## Update strategy for Deployments +deploymentUpdate: + type: RollingUpdate + maxUnavailable: 0 + maxSurge: 100% + +## Update strategy for StatefulSets +statefulSetUpdate: + updateStrategy: RollingUpdate + +## Pod priority settings +## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ +## +priorityClassName: "" + +## Pod runtime class name +## ref https://kubernetes.io/docs/concepts/containers/runtime-class/ +## +runtimeClassName: "" + +## Set default rootUser, rootPassword +## rootUser and rootPassword is generated when not set +## Distributed MinIO ref: https://min.io/docs/minio/linux/operations/install-deploy-manage/deploy-minio-multi-node-multi-drive.html +## +rootUser: "" +rootPassword: "" + +## Use existing Secret that store following variables: +## +## | Chart var | .data. in Secret | +## |:----------------------|:-------------------------| +## | rootUser | rootUser | +## | rootPassword | rootPassword | +## +## All mentioned variables will be ignored in values file. +## .data.rootUser and .data.rootPassword are mandatory, +## others depend on enabled status of corresponding sections. +existingSecret: "" + +## Directory on the MinIO pof +certsPath: "/etc/minio/certs/" +configPathmc: "/etc/minio/mc/" + +## Path where PV would be mounted on the MinIO Pod +mountPath: "/export" +## Override the root directory which the minio server should serve from. +## If left empty, it defaults to the value of {{ .Values.mountPath }} +## If defined, it must be a sub-directory of the path specified in {{ .Values.mountPath }} +## +bucketRoot: "" + +# Number of drives attached to a node +drivesPerNode: 1 +# Number of MinIO containers running +replicas: 16 +# Number of expanded MinIO clusters +pools: 1 + +## TLS Settings for MinIO +tls: + enabled: false + ## Create a secret with private.key and public.crt files and pass that here. Ref: https://github.com/minio/minio/tree/master/docs/tls/kubernetes#2-create-kubernetes-secret + certSecret: "" + publicCrt: public.crt + privateKey: private.key + +## Trusted Certificates Settings for MinIO. Ref: https://min.io/docs/minio/linux/operations/network-encryption.html#third-party-certificate-authorities +## Bundle multiple trusted certificates into one secret and pass that here. Ref: https://github.com/minio/minio/tree/master/docs/tls/kubernetes#2-create-kubernetes-secret +## When using self-signed certificates, remember to include MinIO's own certificate in the bundle with key public.crt. +## If certSecret is left empty and tls is enabled, this chart installs the public certificate from .Values.tls.certSecret. +trustedCertsSecret: "" + +## Enable persistence using Persistent Volume Claims +## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ +## +persistence: + enabled: true + annotations: {} + + ## A manually managed Persistent Volume and Claim + ## Requires persistence.enabled: true + ## If defined, PVC must be created manually before volume will be bound + existingClaim: "" + + ## minio data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + ## Storage class of PV to bind. By default it looks for standard storage class. + ## If the PV uses a different storage class, specify that here. + storageClass: "" + volumeName: "" + accessMode: ReadWriteOnce + size: 500Gi + + ## If subPath is set mount a sub folder of a volume instead of the root of the volume. + ## This is especially handy for volume plugins that don't natively support sub mounting (like glusterfs). + ## + subPath: "" + +## Expose the MinIO service to be accessed from outside the cluster (LoadBalancer service). +## or access it from within the cluster (ClusterIP service). Set the service type and the port to serve it. +## ref: http://kubernetes.io/docs/user-guide/services/ +## +service: + type: ClusterIP + clusterIP: ~ + port: "9000" + nodePort: 32000 + loadBalancerIP: ~ + externalIPs: [] + annotations: {} + + ## service.loadBalancerSourceRanges Addresses that are allowed when service is LoadBalancer + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## + #loadBalancerSourceRanges: + # - 10.10.10.0/24 + loadBalancerSourceRanges: [] + + ## service.externalTrafficPolicy minio service external traffic policy + ## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + +## Configure Ingress based on the documentation here: https://kubernetes.io/docs/concepts/services-networking/ingress/ +## + +ingress: + enabled: false + ingressClassName: ~ + labels: {} + # node-role.kubernetes.io/ingress: platform + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + # kubernetes.io/ingress.allow-http: "false" + # kubernetes.io/ingress.global-static-ip-name: "" + # nginx.ingress.kubernetes.io/secure-backends: "true" + # nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + # nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0 + path: / + hosts: + - minio-example.local + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +consoleService: + type: ClusterIP + clusterIP: ~ + port: "9001" + nodePort: 32001 + loadBalancerIP: ~ + externalIPs: [] + annotations: {} + ## consoleService.loadBalancerSourceRanges Addresses that are allowed when service is LoadBalancer + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## + #loadBalancerSourceRanges: + # - 10.10.10.0/24 + loadBalancerSourceRanges: [] + + ## servconsoleServiceice.externalTrafficPolicy minio service external traffic policy + ## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + +consoleIngress: + enabled: false + ingressClassName: ~ + labels: {} + # node-role.kubernetes.io/ingress: platform + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + # kubernetes.io/ingress.allow-http: "false" + # kubernetes.io/ingress.global-static-ip-name: "" + # nginx.ingress.kubernetes.io/secure-backends: "true" + # nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + # nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0 + path: / + hosts: + - console.minio-example.local + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +## Node labels for pod assignment +## Ref: https://kubernetes.io/docs/user-guide/node-selection/ +## +nodeSelector: {} +tolerations: [] +affinity: {} +topologySpreadConstraints: [] + +## Add stateful containers to have security context, if enabled MinIO will run as this +## user and group NOTE: securityContext is only enabled if persistence.enabled=true +securityContext: + enabled: true + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + fsGroupChangePolicy: "OnRootMismatch" + +containerSecurityContext: + readOnlyRootFilesystem: false + +# Additational pod annotations +podAnnotations: {} + +# Additional pod labels +podLabels: {} + +## Configure resource requests and limits +## ref: http://kubernetes.io/docs/user-guide/compute-resources/ +## +resources: + requests: + memory: 16Gi + +## List of policies to be created after minio install +## +## In addition to default policies [readonly|readwrite|writeonly|consoleAdmin|diagnostics] +## you can define additional policies with custom supported actions and resources +policies: [] +## writeexamplepolicy policy grants creation or deletion of buckets with name +## starting with example. In addition, grants objects write permissions on buckets starting with +## example. +# - name: writeexamplepolicy +# statements: +# - effect: Allow # this is the default +# resources: +# - 'arn:aws:s3:::example*/*' +# actions: +# - "s3:AbortMultipartUpload" +# - "s3:GetObject" +# - "s3:DeleteObject" +# - "s3:PutObject" +# - "s3:ListMultipartUploadParts" +# - resources: +# - 'arn:aws:s3:::example*' +# actions: +# - "s3:CreateBucket" +# - "s3:DeleteBucket" +# - "s3:GetBucketLocation" +# - "s3:ListBucket" +# - "s3:ListBucketMultipartUploads" +## readonlyexamplepolicy policy grants access to buckets with name starting with example. +## In addition, grants objects read permissions on buckets starting with example. +# - name: readonlyexamplepolicy +# statements: +# - resources: +# - 'arn:aws:s3:::example*/*' +# actions: +# - "s3:GetObject" +# - resources: +# - 'arn:aws:s3:::example*' +# actions: +# - "s3:GetBucketLocation" +# - "s3:ListBucket" +# - "s3:ListBucketMultipartUploads" +## conditionsexample policy creates all access to example bucket with aws:username="johndoe" and source ip range 10.0.0.0/8 and 192.168.0.0/24 only +# - name: conditionsexample +# statements: +# - resources: +# - 'arn:aws:s3:::example/*' +# actions: +# - 's3:*' +# conditions: +# - StringEquals: '"aws:username": "johndoe"' +# - IpAddress: | +# "aws:SourceIp": [ +# "10.0.0.0/8", +# "192.168.0.0/24" +# ] +# +## Additional Annotations for the Kubernetes Job makePolicyJob +makePolicyJob: + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + memory: 128Mi + # Command to run after the main command on exit + exitCommand: "" + +## List of users to be created after minio install +## +users: + ## Username, password and policy to be assigned to the user + ## Default policies are [readonly|readwrite|writeonly|consoleAdmin|diagnostics] + ## Add new policies as explained here https://min.io/docs/minio/kubernetes/upstream/administration/identity-access-management.html#access-management + ## NOTE: this will fail if LDAP is enabled in your MinIO deployment + ## make sure to disable this if you are using LDAP. + - accessKey: console + secretKey: console123 + policy: consoleAdmin + # Or you can refer to specific secret + #- accessKey: externalSecret + # existingSecret: my-secret + # existingSecretKey: password + # policy: readonly + +## Additional Annotations for the Kubernetes Job makeUserJob +makeUserJob: + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + memory: 128Mi + # Command to run after the main command on exit + exitCommand: "" + +## List of service accounts to be created after minio install +## +svcaccts: [] + ## accessKey, secretKey and parent user to be assigned to the service accounts + ## Add new service accounts as explained here https://min.io/docs/minio/kubernetes/upstream/administration/identity-access-management/minio-user-management.html#service-accounts + # - accessKey: console-svcacct + # secretKey: console123 + # user: console + ## Or you can refer to specific secret + # - accessKey: externalSecret + # existingSecret: my-secret + # existingSecretKey: password + # user: console + ## You also can pass custom policy + # - accessKey: console-svcacct + # secretKey: console123 + # user: console + # policy: + # statements: + # - resources: + # - 'arn:aws:s3:::example*/*' + # actions: + # - "s3:AbortMultipartUpload" + # - "s3:GetObject" + # - "s3:DeleteObject" + # - "s3:PutObject" + # - "s3:ListMultipartUploadParts" + +makeServiceAccountJob: + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + memory: 128Mi + # Command to run after the main command on exit + exitCommand: "" + +## List of buckets to be created after minio install +## +buckets: [] + # # Name of the bucket + # - name: bucket1 + # # Policy to be set on the + # # bucket [none|download|upload|public] + # policy: none + # # Purge if bucket exists already + # purge: false + # # set versioning for + # # bucket [true|false] + # versioning: false # remove this key if you do not want versioning feature + # # set objectlocking for + # # bucket [true|false] NOTE: versioning is enabled by default if you use locking + # objectlocking: false + # - name: bucket2 + # policy: none + # purge: false + # versioning: true + # # set objectlocking for + # # bucket [true|false] NOTE: versioning is enabled by default if you use locking + # objectlocking: false + +## Additional Annotations for the Kubernetes Job makeBucketJob +makeBucketJob: + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + memory: 128Mi + # Command to run after the main command on exit + exitCommand: "" + +## List of command to run after minio install +## NOTE: the mc command TARGET is always "myminio" +customCommands: + # - command: "admin policy attach myminio consoleAdmin --group='cn=ops,cn=groups,dc=example,dc=com'" + +## Additional Annotations for the Kubernetes Job customCommandJob +customCommandJob: + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + memory: 128Mi + ## Additional volumes to add to the post-job. + extraVolumes: [] + # - name: extra-policies + # configMap: + # name: my-extra-policies-cm + ## Additional volumeMounts to add to the custom commands container when + ## running the post-job. + extraVolumeMounts: [] + # - name: extra-policies + # mountPath: /mnt/extras/ + # Command to run after the main command on exit + exitCommand: "" + +## Merge jobs +postJob: + podAnnotations: {} + annotations: {} + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + nodeSelector: {} + tolerations: [] + affinity: {} + +## Use this field to add environment variables relevant to MinIO server. These fields will be passed on to MinIO container(s) +## when Chart is deployed +environment: + ## Please refer for comprehensive list https://min.io/docs/minio/linux/reference/minio-server/minio-server.html + ## MINIO_SUBNET_LICENSE: "License key obtained from https://subnet.min.io" + ## MINIO_BROWSER: "off" + +## The name of a secret in the same kubernetes namespace which contain secret values +## This can be useful for LDAP password, etc +## The key in the secret must be 'config.env' +## +extraSecret: ~ + +## OpenID Identity Management +## The following section documents environment variables for enabling external identity management using an OpenID Connect (OIDC)-compatible provider. +## See https://min.io/docs/minio/linux/operations/external-iam/configure-openid-external-identity-management.html for a tutorial on using these variables. +oidc: + enabled: false + configUrl: "https://identity-provider-url/.well-known/openid-configuration" + clientId: "minio" + clientSecret: "" + # Provide existing client secret from the Kubernetes Secret resource, existing secret will have priority over `clientId` and/or `clientSecret`` + existingClientSecretName: "" + existingClientIdKey: "" + existingClientSecretKey: "" + claimName: "policy" + scopes: "openid,profile,email" + redirectUri: "https://console-endpoint-url/oauth_callback" + # Can leave empty + claimPrefix: "" + comment: "" + displayName: "" + +networkPolicy: + enabled: false + # Specifies whether the policies created will be standard Network Policies (flavor: kubernetes) + # or Cilium Network Policies (flavor: cilium) + flavor: kubernetes + allowExternal: true + # only when using flavor: cilium + egressEntities: + - kube-apiserver + +## PodDisruptionBudget settings +## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ +## +podDisruptionBudget: + enabled: false + maxUnavailable: 1 + +## Specify the service account to use for the MinIO pods. If 'create' is set to 'false' +## and 'name' is left unspecified, the account 'default' will be used. +serviceAccount: + create: true + ## The name of the service account to use. If 'create' is 'true', a service account with that name + ## will be created. + name: "minio-sa" + +metrics: + serviceMonitor: + enabled: false + # scrape each node/pod individually for additional metrics + includeNode: false + public: true + additionalLabels: {} + annotations: {} + # for node metrics + relabelConfigs: {} + # for cluster metrics + relabelConfigsCluster: {} + # metricRelabelings: + # - regex: (server|pod) + # action: labeldrop + namespace: ~ + # Scrape interval, for example `interval: 30s` + interval: ~ + # Scrape timeout, for example `scrapeTimeout: 10s` + scrapeTimeout: ~ + +## ETCD settings: https://github.com/minio/minio/blob/master/docs/sts/etcd.md +## Define endpoints to enable this section. +etcd: + endpoints: [] + pathPrefix: "" + corednsPathPrefix: "" + clientCert: "" + clientCertKey: "" diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/.helmignore b/charts/mayastor/charts/loki/charts/rollout-operator/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/Chart.yaml b/charts/mayastor/charts/loki/charts/rollout-operator/Chart.yaml new file mode 100644 index 0000000..efd581c --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v2 +appVersion: v0.24.0 +description: Grafana rollout-operator +home: https://github.com/grafana/rollout-operator +kubeVersion: ^1.10.0-0 +name: rollout-operator +type: application +version: 0.24.0 diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/README.md b/charts/mayastor/charts/loki/charts/rollout-operator/README.md new file mode 100644 index 0000000..9e676ea --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/README.md @@ -0,0 +1,72 @@ +# Grafana rollout-operator Helm Chart + +Helm chart for deploying [Grafana rollout-operator](https://github.com/grafana/rollout-operator) to Kubernetes. + +# rollout-operator + +![Version: 0.24.0](https://img.shields.io/badge/Version-0.24.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.24.0](https://img.shields.io/badge/AppVersion-v0.24.0-informational?style=flat-square) + +Grafana rollout-operator + +## Requirements + +Kubernetes: `^1.10.0-0` + +## Installation + +This section describes various use cases for installation, upgrade and migration from different systems and versions. + +### Preparation + +These are the common tasks to perform before any of the use cases. + +```bash +# Add the repository +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +### Installation of Grafana Rollout Operator + +```bash +helm install -n grafana/rollout-operator +``` + +The Grafana rollout-operator should be installed in the same namespace as the statefulsets it is operating upon. +It is not a highly available application and runs as a single pod. + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | | +| fullnameOverride | string | `""` | | +| global.commonLabels | object | `{}` | Common labels for all object directly managed by this chart. | +| hostAliases | list | `[]` | hostAliases to add | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.repository | string | `"grafana/rollout-operator"` | | +| image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | +| imagePullSecrets | list | `[]` | | +| minReadySeconds | int | `10` | | +| nameOverride | string | `""` | | +| nodeSelector | object | `{}` | | +| podAnnotations | object | `{}` | Pod Annotations | +| podLabels | object | `{}` | Pod (extra) Labels | +| podSecurityContext | object | `{}` | | +| priorityClassName | string | `""` | | +| resources.limits.memory | string | `"200Mi"` | | +| resources.requests.cpu | string | `"100m"` | | +| resources.requests.memory | string | `"100Mi"` | | +| securityContext | object | `{}` | | +| serviceAccount.annotations | object | `{}` | Annotations to add to the service account | +| serviceAccount.create | bool | `true` | Specifies whether a service account should be created | +| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | +| serviceMonitor.annotations | object | `{}` | ServiceMonitor annotations | +| serviceMonitor.enabled | bool | `false` | Create ServiceMonitor to scrape metrics for Prometheus | +| serviceMonitor.interval | string | `nil` | ServiceMonitor scrape interval | +| serviceMonitor.labels | object | `{}` | Additional ServiceMonitor labels | +| serviceMonitor.namespace | string | `nil` | Alternative namespace for ServiceMonitor resources | +| serviceMonitor.namespaceSelector | object | `{}` | Namespace selector for ServiceMonitor resources | +| serviceMonitor.relabelings | list | `[]` | ServiceMonitor relabel configs to apply to samples before scraping https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig | +| serviceMonitor.scrapeTimeout | string | `nil` | ServiceMonitor scrape timeout in Go duration format (e.g. 15s) | +| tolerations | list | `[]` | | diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/README.md.gotmpl b/charts/mayastor/charts/loki/charts/rollout-operator/README.md.gotmpl new file mode 100644 index 0000000..0ac2d47 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/README.md.gotmpl @@ -0,0 +1,38 @@ +# Grafana rollout-operator Helm Chart + +Helm chart for deploying [Grafana rollout-operator]({{ template "chart.homepage" . }}) to Kubernetes. + +{{ template "chart.header" . }} + +{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} + +{{ template "chart.description" . }} + +{{ template "chart.sourcesSection" . }} + +{{ template "chart.requirementsSection" . }} + +## Installation + +This section describes various use cases for installation, upgrade and migration from different systems and versions. + +### Preparation + +These are the common tasks to perform before any of the use cases. + +```bash +# Add the repository +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +### Installation of Grafana Rollout Operator + +```bash +helm install -n grafana/rollout-operator +``` + +The Grafana rollout-operator should be installed in the same namespace as the statefulsets it is operating upon. +It is not a highly available application and runs as a single pod. + +{{ template "chart.valuesSection" . }} diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/templates/NOTES.txt b/charts/mayastor/charts/loki/charts/rollout-operator/templates/NOTES.txt new file mode 100644 index 0000000..a76e5ba --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/templates/NOTES.txt @@ -0,0 +1,10 @@ +Repo : {{ .Chart.Home }} + +Validation: + +Check the logs of the pod and ensure messages for reconcilliation of the statefulsets are present. +``` +kubectl logs -n {{ .Release.Namespace }} -l {{ include "cli.labels" . }} +``` +Example log line: +level=debug ts=2022-04-20T13:59:52.783051541Z msg="reconciling StatefulSet" statefulset=mimir-store-gateway-zone-a diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/templates/_helpers.tpl b/charts/mayastor/charts/loki/charts/rollout-operator/templates/_helpers.tpl new file mode 100644 index 0000000..68ae702 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/templates/_helpers.tpl @@ -0,0 +1,82 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "rollout-operator.name" -}} +{{- default (include "rollout-operator.chartName" .) .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +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 "rollout-operator.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default (include "rollout-operator.chartName" .) .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Recalculate the chart name, because it may be sub-chart included as rollout_operator, +and _ is not valid in resource names. +*/}} +{{- define "rollout-operator.chartName" -}} +{{- print .Chart.Name | replace "_" "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "rollout-operator.chart" -}} +{{- printf "%s-%s" (include "rollout-operator.chartName" .) .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "rollout-operator.labels" -}} +helm.sh/chart: {{ include "rollout-operator.chart" . }} +{{ include "rollout-operator.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- with .Values.global.commonLabels }} +{{ toYaml . }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "rollout-operator.selectorLabels" -}} +app.kubernetes.io/name: {{ include "rollout-operator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "rollout-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "rollout-operator.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + + +{{- define "cli.labels" -}} +{{- $list := list -}} +{{- range $k, $v := ( include "rollout-operator.selectorLabels" . | fromYaml ) -}} +{{- $list = append $list (printf "%s=%s" $k $v) -}} +{{- end -}} +{{ join "," $list }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/templates/deployment.yaml b/charts/mayastor/charts/loki/charts/rollout-operator/templates/deployment.yaml new file mode 100644 index 0000000..d35b866 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/templates/deployment.yaml @@ -0,0 +1,74 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "rollout-operator.fullname" . }} + labels: + {{- include "rollout-operator.labels" . | nindent 4 }} +spec: + replicas: 1 + minReadySeconds: {{ .Values.minReadySeconds }} + selector: + matchLabels: + {{- include "rollout-operator.selectorLabels" . | nindent 6 }} + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "rollout-operator.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "rollout-operator.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: rollout-operator + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - -kubernetes.namespace={{ .Release.Namespace }} + ports: + - name: http-metrics + containerPort: 8001 + protocol: TCP + readinessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 5 + timeoutSeconds: 1 + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/templates/role.yaml b/charts/mayastor/charts/loki/charts/rollout-operator/templates/role.yaml new file mode 100644 index 0000000..7bc2570 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/templates/role.yaml @@ -0,0 +1,30 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "rollout-operator.fullname" . }} + labels: + {{- include "rollout-operator.labels" . | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - list + - get + - watch + - delete +- apiGroups: + - apps + resources: + - statefulsets + verbs: + - list + - get + - watch +- apiGroups: + - apps + resources: + - statefulsets/status + verbs: + - update diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/templates/rolebinding.yaml b/charts/mayastor/charts/loki/charts/rollout-operator/templates/rolebinding.yaml new file mode 100644 index 0000000..d1cfe68 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/templates/rolebinding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "rollout-operator.fullname" . }} + labels: + {{- include "rollout-operator.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "rollout-operator.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ include "rollout-operator.serviceAccountName" . }} diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/templates/service.yaml b/charts/mayastor/charts/loki/charts/rollout-operator/templates/service.yaml new file mode 100644 index 0000000..60ce5b1 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/templates/service.yaml @@ -0,0 +1,18 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "rollout-operator.fullname" . }} + labels: + {{- include "rollout-operator.labels" . | nindent 4 }} +spec: + type: ClusterIP + clusterIP: None + ports: + - port: 8001 + targetPort: http-metrics + protocol: TCP + name: http-metrics + selector: + {{- include "rollout-operator.selectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/templates/serviceaccount.yaml b/charts/mayastor/charts/loki/charts/rollout-operator/templates/serviceaccount.yaml new file mode 100644 index 0000000..37698a4 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "rollout-operator.serviceAccountName" . }} + labels: + {{- include "rollout-operator.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/templates/servicemonitor.yaml b/charts/mayastor/charts/loki/charts/rollout-operator/templates/servicemonitor.yaml new file mode 100644 index 0000000..8fa7c1b --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/templates/servicemonitor.yaml @@ -0,0 +1,36 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "rollout-operator.fullname" . }} + {{- with .Values.serviceMonitor.namespace }} + namespace: {{ . }} + {{- end }} + labels: + {{- include "rollout-operator.labels" . | nindent 4 }} + {{- with .Values.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.serviceMonitor.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- include "rollout-operator.selectorLabels" . | nindent 6 }} + endpoints: + - port: http-metrics + {{- with .Values.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + scheme: http +{{- end -}} diff --git a/charts/mayastor/charts/loki/charts/rollout-operator/values.yaml b/charts/mayastor/charts/loki/charts/rollout-operator/values.yaml new file mode 100644 index 0000000..1711671 --- /dev/null +++ b/charts/mayastor/charts/loki/charts/rollout-operator/values.yaml @@ -0,0 +1,89 @@ +# Default values for rollout-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + + +global: + # -- Common labels for all object directly managed by this chart. + commonLabels: {} + + +image: + repository: grafana/rollout-operator + pullPolicy: IfNotPresent + # -- Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] + +# -- hostAliases to add +hostAliases: [] +# - ip: 1.2.3.4 +# hostnames: +# - domain.tld + +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # -- Specifies whether a service account should be created + create: true + # -- Annotations to add to the service account + annotations: {} + # -- The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +# -- Pod Annotations +podAnnotations: {} + +# -- Pod (extra) Labels +podLabels: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +resources: + limits: + # cpu: "1" + memory: 200Mi + requests: + cpu: 100m + memory: 100Mi + +minReadySeconds: 10 + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +priorityClassName: "" + +serviceMonitor: + # -- Create ServiceMonitor to scrape metrics for Prometheus + enabled: false + # -- Alternative namespace for ServiceMonitor resources + namespace: null + # -- Namespace selector for ServiceMonitor resources + namespaceSelector: {} + # -- ServiceMonitor annotations + annotations: {} + # -- Additional ServiceMonitor labels + labels: {} + # -- ServiceMonitor scrape interval + interval: null + # -- ServiceMonitor scrape timeout in Go duration format (e.g. 15s) + scrapeTimeout: null + # -- ServiceMonitor relabel configs to apply to samples before scraping + # https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + relabelings: [] diff --git a/charts/mayastor/charts/loki/distributed-values.yaml b/charts/mayastor/charts/loki/distributed-values.yaml new file mode 100644 index 0000000..78a1f11 --- /dev/null +++ b/charts/mayastor/charts/loki/distributed-values.yaml @@ -0,0 +1,71 @@ +--- +loki: + schemaConfig: + configs: + - from: 2024-04-01 + store: tsdb + object_store: s3 + schema: v13 + index: + prefix: loki_index_ + period: 24h + ingester: + chunk_encoding: snappy + tracing: + enabled: true + querier: + # Default is 4, if you have enough memory and CPU you can increase, reduce if OOMing + max_concurrent: 4 + +#gateway: +# ingress: +# enabled: true +# hosts: +# - host: FIXME +# paths: +# - path: / +# pathType: Prefix + +deploymentMode: Distributed + +ingester: + replicas: 3 +querier: + replicas: 3 + maxUnavailable: 2 +queryFrontend: + replicas: 2 + maxUnavailable: 1 +queryScheduler: + replicas: 2 +distributor: + replicas: 3 + maxUnavailable: 2 +compactor: + replicas: 1 +indexGateway: + replicas: 2 + maxUnavailable: 1 + +# optional experimental components +bloomPlanner: + replicas: 0 +bloomBuilder: + replicas: 0 +bloomGateway: + replicas: 0 + +# Enable minio for storage +minio: + enabled: true + +# Zero out replica counts of other deployment modes +backend: + replicas: 0 +read: + replicas: 0 +write: + replicas: 0 + +singleBinary: + replicas: 0 diff --git a/charts/mayastor/charts/loki/docs/examples/README.md b/charts/mayastor/charts/loki/docs/examples/README.md new file mode 100644 index 0000000..84cbae3 --- /dev/null +++ b/charts/mayastor/charts/loki/docs/examples/README.md @@ -0,0 +1,4 @@ +## Introduction +The Helm Charts found under the examples directory are getting started examples which you can use to deploy Loki using the Simple Scalable architecture quickly. Currently, the examples include: +- [Deploying Grafana Enterprise Logs (Loki in Enterprise mode)](https://github.com/grafana/loki/tree/main/production/helm/loki/docs/examples/enterprise) +- [Deploying Loki OSS](https://github.com/grafana/loki/tree/main/production/helm/loki/docs/examples/oss) diff --git a/charts/mayastor/charts/loki/docs/examples/enterprise/README.md b/charts/mayastor/charts/loki/docs/examples/enterprise/README.md new file mode 100644 index 0000000..82c0d28 --- /dev/null +++ b/charts/mayastor/charts/loki/docs/examples/enterprise/README.md @@ -0,0 +1,28 @@ +## Introduction +This example gives you an example or getting started overrides value file for deploying Loki (Enterprise Licensed) using the Simple Scalable architecture in GKE and using GCS. + +## Installation of Helm Chart +These instructions assume you already have access to a Kubernetes cluster, GCS Bucket and GCP Service Account which has read/write permissions to that GCS Bucket. + +### Populate Secret Values +Populate the [enterprise-secrets.yaml](./enterprise-secrets.yaml) so that: +- The `gcp_service_account.json` secret has the contents of your GCP Service Account JSON key. +- The `license.jwt` secret has the contents of your Grafana Enterprise Logs license key given to your by Grafana Labs. + +Deploy the secrets file to your k8s cluster with the command: + +`kubectl apply -f enterprise-secrets.yaml` + +### Configure the Helm Chart +Open [overrides-enterprise-gcs.yaml](./overrides-enterprise-gcs.yaml) and replace `{YOUR_GCS_BUCKET}` with the name of your GCS bucket. If there are other things you'd like to configure, view the core [Values.yaml file](https://github.com/grafana/loki/blob/main/production/helm/loki/values.yaml) and override anything else you need to within the overrides-enterprise-gcs.yaml file. + +### Install the Helm chart + +`helm upgrade --install --values {PATH_TO_YOUR_OVERRIDES_YAML_FILE} {YOUR_RELEASE_NAME} grafana/loki-simple-scalable --namespace {KUBERNETES_NAMESPACE}` + +### Get the Token for Grafana to connect +`export POD_NAME=$(kubectl get pods --namespace {KUBERNETES_NAMESPACE} -l "job-name=enterprise-logs-tokengen" -o jsonpath="{.items[0].metadata.name}")` + +`kubectl --namespace {KUBERNETES_NAMESPACE} logs $POD_NAME loki | grep Token` + +Take note of this token, you will need it when connecting Grafana Enterprise Logs to Grafana. diff --git a/charts/mayastor/charts/loki/docs/examples/enterprise/enterprise-secrets.yaml b/charts/mayastor/charts/loki/docs/examples/enterprise/enterprise-secrets.yaml new file mode 100644 index 0000000..698e94b --- /dev/null +++ b/charts/mayastor/charts/loki/docs/examples/enterprise/enterprise-secrets.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Secret +metadata: + name: gel-secrets +type: Opaque +stringData: + gcp_service_account.json: | + { + GCP_SERVICE_ACCOUNT_JSON_HERE + } + + license.jwt: LICENSE_HERE diff --git a/charts/mayastor/charts/loki/docs/examples/enterprise/overrides-enterprise-gcs.yaml b/charts/mayastor/charts/loki/docs/examples/enterprise/overrides-enterprise-gcs.yaml new file mode 100644 index 0000000..01210d3 --- /dev/null +++ b/charts/mayastor/charts/loki/docs/examples/enterprise/overrides-enterprise-gcs.yaml @@ -0,0 +1,83 @@ +enterprise: + enabled: true + useExternalLicense: true + externalLicenseName: gel-secrets + tokengen: + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/gel_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: gel-secrets + mountPath: "/etc/gel_secrets" + extraVolumes: + - name: gel-secrets + secret: + secretName: gel-secrets + items: + - key: license.jwt + path: license.jwt + - key: gcp_service_account.json + path: gcp_service_account.json +loki: + auth_enabled: true + + storage: + type: gcs + bucketNames: + chunks: {YOUR_GCS_BUCKET} + ruler: {YOUR_GCS_BUCKET} + admin: {YOUR_GCS_BUCKET} + +minio: + enabled: false + +write: + extraEnv: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/gel_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: gel-secrets + mountPath: "/etc/gel_secrets" + extraVolumes: + - name: gel-secrets + secret: + secretName: gel-secrets + items: + - key: license.jwt + path: license.jwt + - key: gcp_service_account.json + path: gcp_service_account.json + +read: + extraEnv: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/gel_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: gel-secrets + mountPath: "/etc/gel_secrets" + extraVolumes: + - name: gel-secrets + secret: + secretName: gel-secrets + items: + - key: license.jwt + path: license.jwt + - key: gcp_service_account.json + path: gcp_service_account.json + +gateway: + extraEnv: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/gel_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: gel-secrets + mountPath: "/etc/gel_secrets" + extraVolumes: + - name: gel-secrets + secret: + secretName: gel-secrets + items: + - key: license.jwt + path: license.jwt + - key: gcp_service_account.json + path: gcp_service_account.json diff --git a/charts/mayastor/charts/loki/docs/examples/oss/README.md b/charts/mayastor/charts/loki/docs/examples/oss/README.md new file mode 100644 index 0000000..9a0a410 --- /dev/null +++ b/charts/mayastor/charts/loki/docs/examples/oss/README.md @@ -0,0 +1,20 @@ +## Introduction +This example gives you an example or getting started overrides value file for deploying Loki (OSS) using the Simple Scalable architecture in GKE and using GCS + +## Installation of Helm Chart +These instructions assume you have already have access to a Kubernetes cluster, GCS Bucket and GCP Service Account which has read/write permissions to that GCS Bucket. + +### Populate Secret Values +Populate the examples/enterprise/enterprise-secrets.yaml so that: +- The gcp_service_account.json secret has the contents of your GCP Service Account JSON key + +Deploy the secrets file to your k8s cluster. + +`kubectl apply -f loki-secrets.yaml` + +### Configure the Helm Chart +Open examples/enterprise/overides-oss-gcs.yaml and replace `{YOUR_GCS_BUCKET}` with the name of your GCS bucket. If there are other things you'd like to configure, view the core [Values.yaml file](https://github.com/grafana/loki/blob/main/production/helm/loki/values.yaml) and override anything else you need to within the overrides-enterprise-gcs.yaml file. + +### Install the Helm chart + +`helm upgrade --install --values {PATH_TO_YOUR_OVERRIDES_YAML_FILE} {YOUR_RELEASE_NAME} grafana/loki-simple-scalable --namespace {KUBERNETES_NAMESPACE}` diff --git a/charts/mayastor/charts/loki/docs/examples/oss/oss-secrets.yaml b/charts/mayastor/charts/loki/docs/examples/oss/oss-secrets.yaml new file mode 100644 index 0000000..4fbf5e7 --- /dev/null +++ b/charts/mayastor/charts/loki/docs/examples/oss/oss-secrets.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: loki-secrets +type: Opaque +stringData: + gcp_service_account.json: | + { + GCP_SERVICE_ACCOUNT_JSON_HERE + } \ No newline at end of file diff --git a/charts/mayastor/charts/loki/docs/examples/oss/overrides-oss-gcs.yaml b/charts/mayastor/charts/loki/docs/examples/oss/overrides-oss-gcs.yaml new file mode 100644 index 0000000..3e94f84 --- /dev/null +++ b/charts/mayastor/charts/loki/docs/examples/oss/overrides-oss-gcs.yaml @@ -0,0 +1,77 @@ +enterprise: + enabled: false + adminApi: + enabled: false + useExternalLicense: false + + config: | + admin_client: + storage: + gcs: + bucket_name: {YOUR_GCS_BUCKET} + auth: + type: trust + auth_enabled: false + cluster_name: loki-logs + +loki: + auth_enabled: false + + commonConfig: + path_prefix: /var/loki + replication_factor: 3 + + storage: + type: gcs + bucketNames: + chunks: {YOUR_GCS_BUCKET} + ruler: {YOUR_GCS_BUCKET} + admin: {YOUR_GCS_BUCKET} + +minio: + enabled: false + +write: + extraEnv: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/loki_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: loki-secrets + mountPath: "/etc/loki_secrets" + extraVolumes: + - name: loki-secrets + secret: + secretName: loki-secrets + items: + - key: gcp_service_account.json + path: gcp_service_account.json + +read: + extraEnv: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/loki_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: loki-secrets + mountPath: "/etc/loki_secrets" + extraVolumes: + - name: loki-secrets + secret: + secretName: loki-secrets + items: + - key: gcp_service_account.json + path: gcp_service_account.json + +gateway: + extraEnv: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/etc/loki_secrets/gcp_service_account.json" + extraVolumeMounts: + - name: loki-secrets + mountPath: "/etc/loki_secrets" + extraVolumes: + - name: loki-secrets + secret: + secretName: loki-secrets + items: + - key: gcp_service_account.json + path: gcp_service_account.json diff --git a/charts/mayastor/charts/loki/reference.md.gotmpl b/charts/mayastor/charts/loki/reference.md.gotmpl new file mode 100644 index 0000000..e7cc2d6 --- /dev/null +++ b/charts/mayastor/charts/loki/reference.md.gotmpl @@ -0,0 +1,52 @@ +--- +title: Helm chart values +menuTitle: Helm chart values +description: Reference for Helm Chart values. +aliases: + - ../../../installation/helm/reference/ +weight: 500 +keywords: [] +--- + + + +# Helm chart values + + + + +This is the generated reference for the Loki Helm Chart values. + +> **Note:** This reference is for the Loki Helm chart version 3.0 or greater. +> If you are using the `grafana/loki-stack` Helm chart from the community repo, +> please refer to the `values.yaml` of the respective Github repository +> [grafana/helm-charts](https://github.com/grafana/helm-charts/tree/main/charts/loki-stack). + + + +{{ define "chart.valuesTableHtml" }} +{{ `{{< responsive-table >}}` }} + + + + + + + + + {{- range .Values }} + + + + + + + {{- end }} + +
KeyTypeDescriptionDefault
{{ .Key }}{{ .Type }}{{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }}{{ template "chart.valueDefaultColumnRender" . }}
+{{ `{{< /responsive-table >}}` }} +{{ end }} + +{{ template "chart.valuesTableHtml" . }} + + diff --git a/charts/mayastor/charts/loki/scenarios/README.md b/charts/mayastor/charts/loki/scenarios/README.md new file mode 100644 index 0000000..a69d8b2 --- /dev/null +++ b/charts/mayastor/charts/loki/scenarios/README.md @@ -0,0 +1,82 @@ +# Loki Helm Scenarios + +These scenarios are used by Github Workflow: [Publish Rendered Helm Chart Diff](../../../../.github/workflows/helm-diff-ci.yml). + +Each scenario is used in a different job execution that will be used to deploy loki inside a K3D cluster in our github action workflow. + +We deploy the scenario with the latest release and then we execute a helm diff with the current version in the workspace, the diff between the release deployed will be posted in the pull request inside a comment like [this](https://github.com/grafana/loki/pull/15734#issuecomment-2592439539) making clear to review. + +>*NOTE*: the helm diff output file will be available for each scenario inside github action to download for 2 days, after this you may need to re-run the job if you would like to download the output files. + +## Add new scenario to the CI + +To add a new scenario in the CI, you would just add a new entry to the matrix configuration: + +``` +strategy: + matrix: + scenario: + - name: New Scenario + values_file: new-scenario-values.yaml + use_k3d: true # or false depending on requirements +``` + +## Run scenarios locally + +All this process that we run in the CI can be done locally, the following steps would explain how. + +## Requirements + +To run locally you will need the following tools in your local environment + +* k3d or any kubernetes cluster +* helm +* [helm-diff plugin](https://github.com/databus23/helm-diff) + +## Run + +Make sure that you are pointing to the kubernetes cluster that you want to apply the chart and validate. + +Create a `${scenario}-values.yaml` file with the configuration that you would like to validate. + +Deploy in your kubernetes cluster the latest released version of the helm chart with your config file: + +```shell + helm install --create-namespace loki-release grafana/loki -f ${scenario}-values.yaml +``` + + Then run the helm diff plugin to compare the local helm chart to see the upgrade changes that will happen: + +```shell + HELM_DIFF_USE_UPGRADE_DRY_RUN: true helm diff upgrade loki-release -f ${scenario}-values.yaml production/helm/loki +``` + +The helm diff plugin will compare all manifests that are created in your local development kubernetes cluster and the generated by helm upgrade operation, the output will be printed in your terminal. + +### Configs for CSP specific + +To compare the changes specifically for a cloud provider the process is similar, the main difference that you will need to have access to the kubernetes cluster with the right permissions inside the cloud provider. + +In case that is not possible, the quick validation can be done in a different way, instead of deploy to the kubernetes cluster, we generate the manifests with helm like this: + +```shell + helm template loki-release grafana/loki -f ${scenario}-values.yaml > release-manifest.yaml +``` + +Then we make the same process with local chart version + +```shell + helm template loki-release production/helm/loki -f ${scenario}-values.yaml > current-manifest.yaml +``` + +As the last step you need to run a diff between both files: + +```shell + diff current-manifest.yaml release-manifest.yaml +``` + +### Known Issues + +* The Github Action won't be able to post the diff comment if the PR is coming from a fork, because of permissions the workflow run from a fork is not able to write in the PR content. + + In this case, to review the output we recommend to download the artifacts in the workflow run and check the outputs. diff --git a/charts/mayastor/charts/loki/scenarios/default-single-binary-values.yaml b/charts/mayastor/charts/loki/scenarios/default-single-binary-values.yaml new file mode 100644 index 0000000..78a1f11 --- /dev/null +++ b/charts/mayastor/charts/loki/scenarios/default-single-binary-values.yaml @@ -0,0 +1,71 @@ +--- +loki: + schemaConfig: + configs: + - from: 2024-04-01 + store: tsdb + object_store: s3 + schema: v13 + index: + prefix: loki_index_ + period: 24h + ingester: + chunk_encoding: snappy + tracing: + enabled: true + querier: + # Default is 4, if you have enough memory and CPU you can increase, reduce if OOMing + max_concurrent: 4 + +#gateway: +# ingress: +# enabled: true +# hosts: +# - host: FIXME +# paths: +# - path: / +# pathType: Prefix + +deploymentMode: Distributed + +ingester: + replicas: 3 +querier: + replicas: 3 + maxUnavailable: 2 +queryFrontend: + replicas: 2 + maxUnavailable: 1 +queryScheduler: + replicas: 2 +distributor: + replicas: 3 + maxUnavailable: 2 +compactor: + replicas: 1 +indexGateway: + replicas: 2 + maxUnavailable: 1 + +# optional experimental components +bloomPlanner: + replicas: 0 +bloomBuilder: + replicas: 0 +bloomGateway: + replicas: 0 + +# Enable minio for storage +minio: + enabled: true + +# Zero out replica counts of other deployment modes +backend: + replicas: 0 +read: + replicas: 0 +write: + replicas: 0 + +singleBinary: + replicas: 0 diff --git a/charts/mayastor/charts/loki/scenarios/default-values.yaml b/charts/mayastor/charts/loki/scenarios/default-values.yaml new file mode 100644 index 0000000..a79baee --- /dev/null +++ b/charts/mayastor/charts/loki/scenarios/default-values.yaml @@ -0,0 +1,16 @@ +--- +loki: + commonConfig: + replication_factor: 1 + useTestSchema: true + storage: + bucketNames: + chunks: chunks + ruler: ruler + admin: admin +read: + replicas: 1 +write: + replicas: 1 +backend: + replicas: 1 diff --git a/charts/mayastor/charts/loki/scenarios/ingress-values.yaml b/charts/mayastor/charts/loki/scenarios/ingress-values.yaml new file mode 100644 index 0000000..ff5ff1e --- /dev/null +++ b/charts/mayastor/charts/loki/scenarios/ingress-values.yaml @@ -0,0 +1,30 @@ +--- +gateway: + ingress: + enabled: true + annotations: {} + hosts: + - host: gateway.loki.example.com + paths: + - path: / + pathType: Prefix +loki: + commonConfig: + replication_factor: 1 + useTestSchema: true + storage: + bucketNames: + chunks: chunks + ruler: ruler + admin: admin +read: + replicas: 1 +write: + replicas: 1 +backend: + replicas: 1 +monitoring: + lokiCanary: + enabled: false +test: + enabled: false diff --git a/charts/mayastor/charts/loki/scenarios/legacy-monitoring-values.yaml b/charts/mayastor/charts/loki/scenarios/legacy-monitoring-values.yaml new file mode 100644 index 0000000..ad520e5 --- /dev/null +++ b/charts/mayastor/charts/loki/scenarios/legacy-monitoring-values.yaml @@ -0,0 +1,27 @@ +--- +loki: + commonConfig: + replication_factor: 1 + useTestSchema: true + storage: + bucketNames: + chunks: chunks + ruler: ruler + admin: admin +read: + replicas: 1 +write: + replicas: 1 +backend: + replicas: 1 +monitoring: + enabled: true + selfMonitoring: + enabled: true + grafanaAgent: + installOperator: true + serviceMonitor: + labels: + release: "prometheus" +test: + prometheusAddress: "http://prometheus-kube-prometheus-prometheus.prometheus.svc.cluster.local.:9090" diff --git a/charts/mayastor/charts/loki/scenarios/simple-scalable-aws-kube-irsa-values.yaml b/charts/mayastor/charts/loki/scenarios/simple-scalable-aws-kube-irsa-values.yaml new file mode 100644 index 0000000..28c6c3b --- /dev/null +++ b/charts/mayastor/charts/loki/scenarios/simple-scalable-aws-kube-irsa-values.yaml @@ -0,0 +1,67 @@ +loki: + # -- Storage config. Providing this will automatically populate all necessary storage configs in the templated config. + storage: + # Loki requires a bucket for chunks and the ruler. GEL requires a third bucket for the admin API. + # Please provide these values if you are using object storage. + bucketNames: + chunks: aws-s3-chunks-bucket + ruler: aws-s3-ruler-bucket + admin: aws-s3-admin-bucket + type: s3 + s3: + region: eu-central-1 + # -- Check https://grafana.com/docs/loki/latest/configuration/#schema_config for more info on how to configure schemas + schemaConfig: + configs: + - from: "2023-09-19" + index: + period: 1d + prefix: tsdb_index_ + object_store: s3 + schema: v13 + store: tsdb +###################################################################################################################### +# +# Enterprise Loki Configs +# +###################################################################################################################### + +# -- Configuration for running Enterprise Loki +enterprise: + # Enable enterprise features, license must be provided + enabled: true + # -- Grafana Enterprise Logs license + license: + contents: "content of licence" + tokengen: + annotations: { + eks.amazonaws.com/role-arn: arn:aws:iam::2222222:role/test-role + } + # -- Configuration for `provisioner` target + provisioner: + # -- Additional annotations for the `provisioner` Job + annotations: { + eks.amazonaws.com/role-arn: arn:aws:iam::2222222:role/test-role + } +###################################################################################################################### +# +# Service Accounts and Kubernetes RBAC +# +###################################################################################################################### +serviceAccount: + # -- Annotations for the service account + annotations: + eks.amazonaws.com/role-arn: arn:aws:iam::2222222:role/test-role + +# Configuration for the write pod(s) +write: + persistence: + storageClass: gp2 +# -- Configuration for the read pod(s) +read: + persistence: + storageClass: gp2 +# -- Configuration for the backend pod(s) +backend: + persistence: + storageClass: gp2 diff --git a/charts/mayastor/charts/loki/scenarios/simple-thanos-values.yaml b/charts/mayastor/charts/loki/scenarios/simple-thanos-values.yaml new file mode 100644 index 0000000..814b1e4 --- /dev/null +++ b/charts/mayastor/charts/loki/scenarios/simple-thanos-values.yaml @@ -0,0 +1,53 @@ +--- +loki: + commonConfig: + replication_factor: 1 + useTestSchema: true + + storage: + type: s3 + + use_thanos_objstore: true + + object_store: + type: s3 + + s3: + access_key_id: thanos-minio + secret_access_key: thanos-minio123 + region: us-east-1 + insecure: true + endpoint: http://minio.minio.svc.cluster.local:9000 + http: + tls_config: + insecure_skip_verify: true + + # GCS configuration (when type is "GCS") + gcs: + bucket_name: test-gcs # Name of the bucket + service_account: service-account-test.json # Optional service account JSON + + # Azure configuration (when type is "AZURE") + azure: + account_name: azure-test # Storage account name + account_key: 1234567890 # Optional storage account key + + bucketNames: + chunks: chunks_thanos + ruler: ruler_thanos + admin: admin_thanos + +enterprise: + enabled: true + adminApi: + enabled: true + +minio: + enabled: true + +read: + replicas: 1 +write: + replicas: 1 +backend: + replicas: 1 diff --git a/charts/mayastor/charts/loki/simple-scalable-values.yaml b/charts/mayastor/charts/loki/simple-scalable-values.yaml new file mode 100644 index 0000000..78132b6 --- /dev/null +++ b/charts/mayastor/charts/loki/simple-scalable-values.yaml @@ -0,0 +1,63 @@ +--- +loki: + schemaConfig: + configs: + - from: 2024-04-01 + store: tsdb + object_store: s3 + schema: v13 + index: + prefix: loki_index_ + period: 24h + ingester: + chunk_encoding: snappy + tracing: + enabled: true + querier: + # Default is 4, if you have enough memory and CPU you can increase, reduce if OOMing + max_concurrent: 4 + +#gateway: +# ingress: +# enabled: true +# hosts: +# - host: FIXME +# paths: +# - path: / +# pathType: Prefix + +deploymentMode: SimpleScalable + +backend: + replicas: 3 +read: + replicas: 3 +write: + replicas: 3 + +# Enable minio for storage +minio: + enabled: true + +# Zero out replica counts of other deployment modes +singleBinary: + replicas: 0 + +ingester: + replicas: 0 +querier: + replicas: 0 +queryFrontend: + replicas: 0 +queryScheduler: + replicas: 0 +distributor: + replicas: 0 +compactor: + replicas: 0 +indexGateway: + replicas: 0 +bloomCompactor: + replicas: 0 +bloomGateway: + replicas: 0 diff --git a/charts/mayastor/charts/loki/single-binary-values.yaml b/charts/mayastor/charts/loki/single-binary-values.yaml new file mode 100644 index 0000000..584f0fb --- /dev/null +++ b/charts/mayastor/charts/loki/single-binary-values.yaml @@ -0,0 +1,79 @@ +--- +loki: + commonConfig: + replication_factor: 1 + schemaConfig: + configs: + - from: 2024-04-01 + store: tsdb + object_store: s3 + schema: v13 + index: + prefix: loki_index_ + period: 24h + ingester: + chunk_encoding: snappy + tracing: + enabled: true + querier: + # Default is 4, if you have enough memory and CPU you can increase, reduce if OOMing + max_concurrent: 2 + +#gateway: +# ingress: +# enabled: true +# hosts: +# - host: FIXME +# paths: +# - path: / +# pathType: Prefix + +deploymentMode: SingleBinary +singleBinary: + replicas: 1 + resources: + limits: + cpu: 3 + memory: 4Gi + requests: + cpu: 2 + memory: 2Gi + extraEnv: + # Keep a little bit lower than memory limits + - name: GOMEMLIMIT + value: 3750MiB + +chunksCache: + # default is 500MB, with limited memory keep this smaller + writebackSizeLimit: 10MB + +# Enable minio for storage +minio: + enabled: true + +# Zero out replica counts of other deployment modes +backend: + replicas: 0 +read: + replicas: 0 +write: + replicas: 0 + +ingester: + replicas: 0 +querier: + replicas: 0 +queryFrontend: + replicas: 0 +queryScheduler: + replicas: 0 +distributor: + replicas: 0 +compactor: + replicas: 0 +indexGateway: + replicas: 0 +bloomCompactor: + replicas: 0 +bloomGateway: + replicas: 0 diff --git a/charts/mayastor/charts/loki/src/.yamllint.yaml b/charts/mayastor/charts/loki/src/.yamllint.yaml new file mode 100644 index 0000000..19e5933 --- /dev/null +++ b/charts/mayastor/charts/loki/src/.yamllint.yaml @@ -0,0 +1,4 @@ +--- +rules: + quoted-strings: + required: true diff --git a/charts/mayastor/charts/loki/src/alerts.yaml.tpl b/charts/mayastor/charts/loki/src/alerts.yaml.tpl new file mode 100644 index 0000000..0aa37b7 --- /dev/null +++ b/charts/mayastor/charts/loki/src/alerts.yaml.tpl @@ -0,0 +1,78 @@ +--- +groups: + - name: "loki_alerts" + rules: +{{- if not (.Values.monitoring.rules.disabled.LokiRequestErrors | default false) }} + - alert: "LokiRequestErrors" + annotations: + message: | + {{`{{`}} $labels.job {{`}}`}} {{`{{`}} $labels.route {{`}}`}} is experiencing {{`{{`}} printf "%.2f" $value {{`}}`}}% errors. + expr: | + 100 * sum(rate(loki_request_duration_seconds_count{status_code=~"5.."}[2m])) by (namespace, job, route) + / + sum(rate(loki_request_duration_seconds_count[2m])) by (namespace, job, route) + > 10 + for: "15m" + labels: + severity: "critical" +{{- if .Values.monitoring.rules.additionalRuleLabels }} +{{ toYaml .Values.monitoring.rules.additionalRuleLabels | indent 10 }} +{{- end }} +{{- end }} +{{- if not (.Values.monitoring.rules.disabled.LokiRequestPanics | default false) }} + - alert: "LokiRequestPanics" + annotations: + message: | + {{`{{`}} $labels.job {{`}}`}} is experiencing {{`{{`}} printf "%.2f" $value {{`}}`}}% increase of panics. + expr: | + sum(increase(loki_panic_total[10m])) by (namespace, job) > 0 + labels: + severity: "critical" +{{- if .Values.monitoring.rules.additionalRuleLabels }} +{{ toYaml .Values.monitoring.rules.additionalRuleLabels | indent 10 }} +{{- end }} +{{- end }} +{{- if not (.Values.monitoring.rules.disabled.LokiRequestLatency | default false) }} + - alert: "LokiRequestLatency" + annotations: + message: | + {{`{{`}} $labels.job {{`}}`}} {{`{{`}} $labels.route {{`}}`}} is experiencing {{`{{`}} printf "%.2f" $value {{`}}`}}s 99th percentile latency. + expr: | + namespace_job_route:loki_request_duration_seconds:99quantile{route!~"(?i).*tail.*"} > 1 + for: "15m" + labels: + severity: "critical" +{{- if .Values.monitoring.rules.additionalRuleLabels }} +{{ toYaml .Values.monitoring.rules.additionalRuleLabels | indent 10 }} +{{- end }} +{{- end }} +{{- if not (.Values.monitoring.rules.disabled.LokiTooManyCompactorsRunning | default false) }} + - alert: "LokiTooManyCompactorsRunning" + annotations: + message: | + {{`{{`}} $labels.cluster {{`}}`}} {{`{{`}} $labels.namespace {{`}}`}} has had {{`{{`}} printf "%.0f" $value {{`}}`}} compactors running for more than 5m. Only one compactor should run at a time. + expr: | + sum(loki_boltdb_shipper_compactor_running) by (cluster, namespace) > 1 + for: "5m" + labels: + severity: "warning" +{{- if .Values.monitoring.rules.additionalRuleLabels }} +{{ toYaml .Values.monitoring.rules.additionalRuleLabels | indent 10 }} +{{- end }} +{{- end }} +{{- if not (.Values.monitoring.rules.disabled.LokiCanaryLatency | default false) }} + - name: "loki_canaries_alerts" + rules: + - alert: "LokiCanaryLatency" + annotations: + message: | + {{`{{`}} $labels.job {{`}}`}} is experiencing {{`{{`}} printf "%.2f" $value {{`}}`}}s 99th percentile latency. + expr: | + histogram_quantile(0.99, sum(rate(loki_canary_response_latency_seconds_bucket[5m])) by (le, namespace, job)) > 5 + for: "15m" + labels: + severity: "warning" +{{- if .Values.monitoring.rules.additionalRuleLabels }} +{{ toYaml .Values.monitoring.rules.additionalRuleLabels | indent 10 }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/src/dashboards/loki-chunks.json b/charts/mayastor/charts/loki/src/dashboards/loki-chunks.json new file mode 100644 index 0000000..bec1997 --- /dev/null +++ b/charts/mayastor/charts/loki/src/dashboards/loki-chunks.json @@ -0,0 +1,1336 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(loki_ingester_memory_chunks{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "series", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Series", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(loki_ingester_memory_chunks{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}) / sum(loki_ingester_memory_streams{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "chunks", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Chunks per series", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Active Series / Chunks", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_utilization_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_ingester_chunk_utilization_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_ingester_chunk_utilization_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) * 1 / sum(rate(loki_ingester_chunk_utilization_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Utilization", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_age_seconds_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_ingester_chunk_age_seconds_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_ingester_chunk_age_seconds_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) * 1e3 / sum(rate(loki_ingester_chunk_age_seconds_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Age", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Flush Stats", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_entries_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_ingester_chunk_entries_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)) * 1", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_ingester_chunk_entries_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) * 1 / sum(rate(loki_ingester_chunk_entries_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Log Entries Per Chunk", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_chunk_store_index_entries_per_chunk_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m])) / sum(rate(loki_chunk_store_index_entries_per_chunk_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Index Entries", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Index Entries Per Chunk", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Flush Stats", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "loki_ingester_flush_queue_length{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"} or cortex_ingester_flush_queue_length{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Queue Length", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { + "1xx": "#EAB839", + "2xx": "#7EB26D", + "3xx": "#6ED0E0", + "4xx": "#EF843C", + "5xx": "#E24D42", + "error": "#E24D42", + "success": "#7EB26D" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_ingester_chunk_age_seconds_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{status}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Flush Rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Flush Stats", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 9, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_ingester_chunks_flushed_total{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Chunks Flushed/Second", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (reason) (rate(loki_ingester_chunks_flushed_total{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) / ignoring(reason) group_left sum(rate(loki_ingester_chunks_flushed_total{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{reason}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Chunk Flush Reason", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": 1, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": 1, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Flush Stats", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "cards": { + "cardPadding": null, + "cardRound": null + }, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateSpectral", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": "$datasource", + "heatmap": { }, + "hideZeroBuckets": false, + "highlightCards": true, + "id": 11, + "legend": { + "show": true + }, + "span": 12, + "targets": [ + { + "expr": "sum by (le) (rate(loki_ingester_chunk_utilization_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval]))", + "format": "heatmap", + "intervalFactor": 2, + "legendFormat": "{{le}}", + "refId": "A" + } + ], + "title": "Chunk Utilization", + "tooltip": { + "show": true, + "showHistogram": true + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "xBucketNumber": null, + "xBucketSize": null, + "yAxis": { + "decimals": 0, + "format": "percentunit", + "show": true, + "splitFactor": null + }, + "yBucketBound": "auto" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Utilization", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "cards": { + "cardPadding": null, + "cardRound": null + }, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateSpectral", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": "$datasource", + "heatmap": { }, + "hideZeroBuckets": false, + "highlightCards": true, + "id": 12, + "legend": { + "show": true + }, + "span": 12, + "targets": [ + { + "expr": "sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[$__rate_interval])) by (le)", + "format": "heatmap", + "intervalFactor": 2, + "legendFormat": "{{le}}", + "refId": "A" + } + ], + "title": "Chunk Size Bytes", + "tooltip": { + "show": true, + "showHistogram": true + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "xBucketNumber": null, + "xBucketSize": null, + "yAxis": { + "decimals": 0, + "format": "bytes", + "show": true, + "splitFactor": null + }, + "yBucketBound": "auto" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Utilization", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 13, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[1m])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "p99", + "legendLink": null, + "step": 10 + }, + { + "expr": "histogram_quantile(0.90, sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[1m])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "p90", + "legendLink": null, + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[1m])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "p50", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Chunk Size Quantiles", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Utilization", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.5, sum(rate(loki_ingester_chunk_bounds_hours_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "p50", + "legendLink": null, + "step": 10 + }, + { + "expr": "histogram_quantile(0.99, sum(rate(loki_ingester_chunk_bounds_hours_bucket{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "p99", + "legendLink": null, + "step": 10 + }, + { + "expr": "sum(rate(loki_ingester_chunk_bounds_hours_sum{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m])) / sum(rate(loki_ingester_chunk_bounds_hours_count{cluster=\"$cluster\", job=~\"$namespace/(loki|enterprise-logs)-write\"}[5m]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "avg", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Chunk Duration hours (end-start)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Duration", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Chunks", + "uid": "chunks", + "version": 0 + } \ No newline at end of file diff --git a/charts/mayastor/charts/loki/src/dashboards/loki-deletion.json b/charts/mayastor/charts/loki/src/dashboards/loki-deletion.json new file mode 100644 index 0000000..84bfee6 --- /dev/null +++ b/charts/mayastor/charts/loki/src/dashboards/loki-deletion.json @@ -0,0 +1,632 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "100px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "format": "none", + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(loki_compactor_pending_delete_requests_count{cluster=~\"$cluster\", namespace=~\"$namespace\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Number of Pending Requests", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "singlestat", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "format": "dtdurations", + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max(loki_compactor_oldest_pending_delete_request_age_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\"})", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Oldest Pending Request Age", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "singlestat", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Headlines", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(loki_compactor_delete_requests_received_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[1d]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "received", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Delete Requests Received / Day", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(loki_compactor_delete_requests_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[1d]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "processed", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Delete Requests Processed / Day", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Churn", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(loki_compactor_load_pending_requests_attempts_total{status=\"fail\", cluster=~\"$cluster\", namespace=~\"$namespace\"}[1h]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "failures", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Failures in Loading Delete Requests / Hour", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Failures", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_compactor_deleted_lines{cluster=~\"$cluster\",job=~\"$namespace/(loki|enterprise-logs)-read\"}[$__rate_interval])) by (user)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{user}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Lines Deleted / Sec", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Deleted lines", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Deletion", + "uid": "deletion", + "version": 0 + } \ No newline at end of file diff --git a/charts/mayastor/charts/loki/src/dashboards/loki-logs.json b/charts/mayastor/charts/loki/src/dashboards/loki-logs.json new file mode 100644 index 0000000..0f113cf --- /dev/null +++ b/charts/mayastor/charts/loki/src/dashboards/loki-logs.json @@ -0,0 +1,1073 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": 8, + "iteration": 1583185057230, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 35, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(go_goroutines{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\"})", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "goroutines", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 3, + "y": 0 + }, + "hiddenSeries": false, + "id": 41, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(go_gc_duration_seconds{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\"}) by (quantile)", + "legendFormat": "{{quantile}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "gc duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 6, + "y": 0 + }, + "hiddenSeries": false, + "id": 36, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_cpu_usage_seconds_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "cpu", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 9, + "y": 0 + }, + "hiddenSeries": false, + "id": 40, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\"})", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "working set", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 12, + "y": 0 + }, + "hiddenSeries": false, + "id": 38, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_network_transmit_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "tx", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 15, + "y": 0 + }, + "hiddenSeries": false, + "id": 39, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_network_receive_bytes_total{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "rx", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 18, + "y": 0 + }, + "hiddenSeries": false, + "id": 37, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "increase(kube_pod_container_status_last_terminated_reason{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\"}[30m]) > 0", + "legendFormat": "{{reason}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "restarts", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 3, + "x": 21, + "y": 0 + }, + "hiddenSeries": false, + "id": 42, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(promtail_custom_bad_words_total{cluster=\"$cluster\", exported_namespace=\"$namespace\", exported_pod=~\"$deployment.*\", exported_pod=~\"$pod\", container=~\"$container\"}[5m])) by (level)", + "legendFormat": "{{level}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "bad words", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$logs", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 4 + }, + "hiddenSeries": false, + "id": 31, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "warn", + "color": "#FF780A" + }, + { + "alias": "error", + "color": "#E02F44" + }, + { + "alias": "info", + "color": "#56A64B" + }, + { + "alias": "debug", + "color": "#3274D9" + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate({cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\" } |logfmt| level=~\"$level\" |= \"$filter\" [5m])) by (level)", + "intervalFactor": 3, + "legendFormat": "{{level}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Log Rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "timeseries", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": false, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "$logs", + "gridPos": { + "h": 19, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 29, + "maxDataPoints": "", + "options": { + "showLabels": false, + "showTime": true, + "sortOrder": "Descending", + "wrapLogMessage": true + }, + "targets": [ + { + "expr": "{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\", pod=~\"$pod\", container=~\"$container\"} | logfmt | level=~\"$level\" |= \"$filter\"", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Logs", + "type": "logs" + } + ], + "refresh": "10s", + "rows": [ ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "hide": 0, + "label": null, + "name": "logs", + "options": [ ], + "query": "loki", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "deployment", + "options": [ ], + "query": "label_values(kube_deployment_created{cluster=\"$cluster\", namespace=\"$namespace\"}, deployment)", + "refresh": 0, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "pod", + "options": [ ], + "query": "label_values(kube_pod_container_info{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$deployment.*\"}, pod)", + "refresh": 0, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "container", + "options": [ ], + "query": "label_values(kube_pod_container_info{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"$pod\", pod=~\"$deployment.*\"}, container)", + "refresh": 0, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "selected": true, + "text": "", + "value": "" + }, + "hide": 0, + "includeAll": false, + "label": "", + "multi": true, + "name": "level", + "options": [ + { + "selected": false, + "text": "debug", + "value": "debug" + }, + { + "selected": false, + "text": "info", + "value": "info" + }, + { + "selected": false, + "text": "warn", + "value": "warn" + }, + { + "selected": false, + "text": "error", + "value": "error" + } + ], + "query": "debug,info,warn,error", + "refresh": 0, + "type": "custom" + }, + { + "current": { + "selected": false, + "text": "", + "value": "" + }, + "label": "LogQL Filter", + "name": "filter", + "query": "", + "type": "textbox" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Logs", + "uid": "logs", + "version": 0 + } \ No newline at end of file diff --git a/charts/mayastor/charts/loki/src/dashboards/loki-mixin-recording-rules.json b/charts/mayastor/charts/loki/src/dashboards/loki-mixin-recording-rules.json new file mode 100644 index 0000000..fe49ec7 --- /dev/null +++ b/charts/mayastor/charts/loki/src/dashboards/loki-mixin-recording-rules.json @@ -0,0 +1,657 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [ ], + "type": "dashboard" + }, + "type": "dashboard" + }, + { + "datasource": "${datasource}", + "enable": false, + "expr": "sum by (tenant) (changes(loki_ruler_wal_prometheus_tsdb_wal_truncations_total{tenant=~\"${tenant}\"}[$__rate_interval]))", + "iconColor": "red", + "name": "WAL Truncations", + "target": { + "queryType": "Azure Monitor", + "refId": "Anno" + }, + "titleFormat": "{{tenant}}" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1635347545534, + "links": [ ], + "liveNow": false, + "panels": [ + { + "datasource": "${datasource}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ ], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 1 + } + ] + } + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 2, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "8.3.0-38205pre", + "targets": [ + { + "datasource": "${datasource}", + "exemplar": false, + "expr": "sum(loki_ruler_wal_appender_ready) by (pod, tenant) == 0", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Appenders Not Ready", + "type": "stat" + }, + { + "datasource": "${datasource}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 11, + "x": 2, + "y": 0 + }, + "id": 4, + "options": { + "legend": { + "calcs": [ ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "exemplar": true, + "expr": "sum(rate(loki_ruler_wal_samples_appended_total{tenant=~\"${tenant}\"}[$__rate_interval])) by (tenant) > 0", + "interval": "", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "title": "Samples Appended to WAL per Second", + "type": "timeseries" + }, + { + "datasource": "${datasource}", + "description": "Series are unique combinations of labels", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 11, + "x": 13, + "y": 0 + }, + "id": 5, + "options": { + "legend": { + "calcs": [ ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "exemplar": true, + "expr": "sum(rate(loki_ruler_wal_storage_created_series_total{tenant=~\"${tenant}\"}[$__rate_interval])) by (tenant) > 0", + "interval": "", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "title": "Series Created per Second", + "type": "timeseries" + }, + { + "datasource": "${datasource}", + "description": "Difference between highest timestamp appended to WAL and highest timestamp successfully written to remote storage", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 6, + "options": { + "legend": { + "calcs": [ ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "exemplar": true, + "expr": "loki_ruler_wal_prometheus_remote_storage_highest_timestamp_in_seconds{tenant=~\"${tenant}\"}\n- on (tenant)\n (\n loki_ruler_wal_prometheus_remote_storage_queue_highest_sent_timestamp_seconds{tenant=~\"${tenant}\"}\n or vector(0)\n )", + "interval": "", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "title": "Write Behind", + "type": "timeseries" + }, + { + "datasource": "${datasource}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 10 + }, + "id": 7, + "options": { + "legend": { + "calcs": [ ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "exemplar": true, + "expr": "sum(rate(loki_ruler_wal_prometheus_remote_storage_samples_total{tenant=~\"${tenant}\"}[$__rate_interval])) by (tenant) > 0", + "interval": "", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "title": "Samples Sent per Second", + "type": "timeseries" + }, + { + "datasource": "${datasource}", + "description": "\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 20 + }, + "id": 8, + "options": { + "legend": { + "calcs": [ ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "exemplar": true, + "expr": "sum by (tenant) (loki_ruler_wal_disk_size{tenant=~\"${tenant}\"})", + "interval": "", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "title": "WAL Disk Size", + "type": "timeseries" + }, + { + "datasource": "${datasource}", + "description": "Some number of pending samples is expected, but if remote-write is failing this value will remain high", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ ] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 20 + }, + "id": 9, + "options": { + "legend": { + "calcs": [ ], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "exemplar": true, + "expr": "max(loki_ruler_wal_prometheus_remote_storage_samples_pending{tenant=~\"${tenant}\"}) by (tenant,pod) > 0", + "interval": "", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "title": "Pending Samples", + "type": "timeseries" + } + ], + "schemaVersion": 31, + "style": "dark", + "tags": [ ], + "templating": { + "list": [ + { + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": "Datasource", + "multi": false, + "name": "datasource", + "options": [ ], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": null, + "datasource": "${datasource}", + "definition": "label_values(loki_ruler_wal_samples_appended_total, tenant)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": "Tenant", + "multi": true, + "name": "tenant", + "options": [ ], + "query": { + "query": "label_values(loki_ruler_wal_samples_appended_total, tenant)", + "refId": "StandardVariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { }, + "timezone": "", + "title": "Recording Rules", + "uid": "2xKA_ZK7k", + "version": 9, + "weekStart": "" + } \ No newline at end of file diff --git a/charts/mayastor/charts/loki/src/dashboards/loki-operational.json b/charts/mayastor/charts/loki/src/dashboards/loki-operational.json new file mode 100644 index 0000000..b69db23 --- /dev/null +++ b/charts/mayastor/charts/loki/src/dashboards/loki-operational.json @@ -0,0 +1,6173 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "id": 68, + "iteration": 1588704280892, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "panels": [ + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 17, + "panels": [ ], + "targets": [ ], + "title": "Main", + "type": "row" + }, + { + "aliasColors": { + "5xx": "red" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 4, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\nlabel_replace(\n label_replace(\n rate(loki_request_duration_seconds_count{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\"}[5m]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n\"status\", \"${1}\", \"status_code\", \"([a-z]+)\")\n)", + "legendFormat": "{{status}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Queries/Second", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 10, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "5xx": "red" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 4, + "x": 4, + "y": 1 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\nlabel_replace(\n label_replace(\n rate(loki_request_duration_seconds_count{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push\"}[5m]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n\"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))", + "legendFormat": "{{status}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Pushes/Second", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 10, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 4, + "x": 12, + "y": 1 + }, + "hiddenSeries": false, + "id": 2, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "topk(10, sum(rate(loki_distributor_lines_received_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (tenant))", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Lines Per Tenant (top 10)", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 4, + "x": 16, + "y": 1 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "topk(10, sum(rate(loki_distributor_bytes_received_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (tenant)) / 1024 / 1024", + "legendFormat": "{{tenant}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "MBs Per Tenant (Top 10)", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 4, + "x": 20, + "y": 1 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "increase(kube_pod_container_status_restarts_total{cluster=\"$cluster\", namespace=\"$namespace\"}[10m]) > 0", + "hide": false, + "interval": "", + "legendFormat": "{{container}}-{{pod}}", + "refId": "B" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Container Restarts", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 6 + }, + "hiddenSeries": false, + "id": 9, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".99", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.75, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".9", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.5, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".5", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Push Latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 6 + }, + "hiddenSeries": false, + "id": 12, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".99", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.9, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".9", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.5, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".5", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Distributor Latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 6 + }, + "hiddenSeries": false, + "id": 71, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", status_code!~\"5[0-9]{2}\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[5m])) by (route)", + "interval": "", + "legendFormat": "{{route}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Distributor Success Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "decimals": null, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": "1", + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 11 + }, + "hiddenSeries": false, + "id": 13, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=\"/logproto.Pusher/Push\", cluster=~\"$cluster\"})) * 1e3", + "legendFormat": ".99", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.9, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=\"/logproto.Pusher/Push\", cluster=~\"$cluster\"})) * 1e3", + "hide": false, + "legendFormat": ".9", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.5, sum by (le) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=\"/logproto.Pusher/Push\", cluster=~\"$cluster\"})) * 1e3", + "hide": false, + "legendFormat": ".5", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Ingester Latency Write", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 11 + }, + "hiddenSeries": false, + "id": 72, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", status_code!~\"5[0-9]{2}\", route=\"/logproto.Pusher/Push\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", route=\"/logproto.Pusher/Push\"}[5m])) by (route)", + "interval": "", + "legendFormat": "{{route}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Ingester Success Rate Write", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "decimals": null, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": "1", + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 16 + }, + "hiddenSeries": false, + "id": 10, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"}))", + "legendFormat": "{{route}}-.99", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.9, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"}))", + "legendFormat": "{{route}}-.9", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.5, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"}))", + "legendFormat": "{{route}}-.5", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Query Latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 16 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"})) * 1e3", + "legendFormat": ".99-{{route}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.9, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"})) * 1e3", + "legendFormat": ".9-{{route}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.5, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"api_prom_query|api_prom_labels|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_label|loki_api_v1_label_name_values\", cluster=\"$cluster\"})) * 1e3", + "legendFormat": ".5-{{route}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Querier Latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 16 + }, + "hiddenSeries": false, + "id": 73, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\", status_code!~\"5[0-9]{2}\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\"}[5m])) by (route)", + "interval": "", + "legendFormat": "{{route}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Querier Success Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "decimals": null, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": "1", + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "description": "", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 21 + }, + "hiddenSeries": false, + "id": 15, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\", cluster=\"$cluster\"})) * 1e3", + "legendFormat": ".99-{{route}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.9, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\", cluster=\"$cluster\"})) * 1e3", + "legendFormat": ".9-{{route}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.5, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\", cluster=\"$cluster\"})) * 1e3", + "legendFormat": ".5-{{route}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Ingester Latency Read", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": { } + }, + "overrides": [ ] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 21 + }, + "hiddenSeries": false, + "id": 74, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", status_code!~\"5[0-9]{2}\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"/logproto.Querier/Query|/logproto.Querier/Label|/logproto.Querier/Series|/logproto.Querier/QuerySample|/logproto.Querier/GetChunkIDs\"}[5m])) by (route)", + "interval": "", + "legendFormat": "{{route}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Ingester Success Rate Read", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "decimals": null, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": "1", + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 26 + }, + "id": 110, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 27 + }, + "hiddenSeries": false, + "id": 112, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "topk(10,sum by (tenant, reason) (rate(loki_discarded_samples_total{cluster=\"$cluster\",namespace=\"$namespace\"}[1m])))", + "interval": "", + "legendFormat": "{{ tenant }} - {{ reason }}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Discarded Lines", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "columns": [ ], + "datasource": "$datasource", + "fontSize": "100%", + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 27 + }, + "id": 113, + "pageSize": null, + "panels": [ ], + "showHeader": true, + "sort": { + "col": 3, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "hidden" + }, + { + "alias": "", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "tenant", + "thresholds": [ ], + "type": "string", + "unit": "short" + }, + { + "alias": "", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "reason", + "thresholds": [ ], + "type": "number", + "unit": "short" + }, + { + "alias": "", + "align": "right", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ ], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "expr": "topk(10, sum by (tenant, reason) (sum_over_time(increase(loki_discarded_samples_total{cluster=\"$cluster\",namespace=\"$namespace\"}[1m])[$__range:1m])))", + "format": "table", + "instant": true, + "interval": "", + "legendFormat": "{{ tenant }} - {{ reason }}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Discarded Lines Per Interval", + "transform": "table", + "type": "table-old" + } + ], + "targets": [ ], + "title": "Limits", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 27 + }, + "id": 23, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 28 + }, + "hiddenSeries": false, + "id": 26, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"(loki|enterprise-logs)-write.*\"}", + "intervalFactor": 3, + "legendFormat": "{{pod}}-{{container}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 28 + }, + "hiddenSeries": false, + "id": 27, + "legend": { + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "go_memstats_heap_inuse_bytes{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"(loki|enterprise-logs)-write.*\"}", + "instant": false, + "intervalFactor": 3, + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Memory Usage", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$logs", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 12, + "x": 12, + "y": 28 + }, + "hiddenSeries": false, + "id": 31, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "{}", + "color": "#C4162A" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate({cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\"} | logfmt | level=\"error\"[1m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Error Log Rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": false, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "$logs", + "gridPos": { + "h": 18, + "w": 12, + "x": 12, + "y": 32 + }, + "id": 29, + "options": { + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": true + }, + "panels": [ ], + "targets": [ + { + "expr": "{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\"} | logfmt | level=\"error\"", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Logs", + "type": "logs" + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 35 + }, + "hiddenSeries": false, + "id": 33, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\", status_code!~\"5[0-9]{2}\"}[5m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[5m])) by (route)", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{route}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Success Rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 35 + }, + "hiddenSeries": false, + "id": 32, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_distributor_ingester_append_failures_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (ingester)", + "intervalFactor": 1, + "legendFormat": "{{ingester}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Append Failures By Ingester", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 42 + }, + "hiddenSeries": false, + "id": 34, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_distributor_bytes_received_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (pod)", + "intervalFactor": 1, + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Bytes Received/Second", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 42 + }, + "hiddenSeries": false, + "id": 35, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_distributor_lines_received_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (pod)", + "intervalFactor": 1, + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Lines Received/Second", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Write Path", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 29 + }, + "id": 104, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 30 + }, + "hiddenSeries": false, + "id": 106, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "topk(10,sum by (tenant) (loki_ingester_memory_streams{cluster=\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\"}))", + "interval": "", + "legendFormat": "{{ tenant }}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Active Streams", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 30 + }, + "hiddenSeries": false, + "id": 108, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "topk(10, sum by (tenant) (rate(loki_ingester_streams_created_total{cluster=\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m]) > 0))", + "interval": "", + "legendFormat": "{{ tenant }}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Streams Created/Sec", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Streams", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 30 + }, + "id": 94, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 31 + }, + "hiddenSeries": false, + "id": 102, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "De-Dupe Ratio", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_ingester_chunks_flushed_total{cluster=\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m]))", + "interval": "", + "legendFormat": "Chunks", + "refId": "A" + }, + { + "expr": "sum(increase(loki_chunk_store_deduped_chunks_total{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m]))/sum(increase(loki_ingester_chunks_flushed_total{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m])) < 1", + "interval": "", + "legendFormat": "De-Dupe Ratio", + "refId": "B" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Chunks Flushed/Sec", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "cards": { + "cardPadding": null, + "cardRound": null + }, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateSpectral", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": "$datasource", + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 31 + }, + "heatmap": { }, + "hideZeroBuckets": false, + "highlightCards": true, + "id": 100, + "legend": { + "show": true + }, + "panels": [ ], + "reverseYBuckets": false, + "targets": [ + { + "expr": "sum(rate(loki_ingester_chunk_size_bytes_bucket{cluster=\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m])) by (le)", + "format": "heatmap", + "instant": false, + "interval": "", + "legendFormat": "{{ le }}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Chunk Size Bytes", + "tooltip": { + "show": true, + "showHistogram": false + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "xBucketNumber": null, + "xBucketSize": null, + "yAxis": { + "decimals": 0, + "format": "bytes", + "logBase": 1, + "max": null, + "min": null, + "show": true, + "splitFactor": null + }, + "yBucketBound": "auto", + "yBucketNumber": null, + "yBucketSize": null + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 7, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 39 + }, + "hiddenSeries": false, + "id": 96, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(reason) (rate(loki_ingester_chunks_flushed_total{cluster=~\"$cluster\",job=~\"$namespace/ingester\", namespace=~\"$namespace\"}[$__rate_interval])) / ignoring(reason) group_left sum(rate(loki_ingester_chunks_flushed_total{cluster=~\"$cluster\",job=~\"$namespace/ingester\", namespace=~\"$namespace\"}[$__rate_interval]))", + "interval": "", + "legendFormat": "{{ reason }}" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Chunk Flush Reason %", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": "1", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "cards": { + "cardPadding": null, + "cardRound": null + }, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateSpectral", + "exponent": 0.5, + "max": null, + "min": null, + "mode": "spectrum" + }, + "dataFormat": "tsbuckets", + "datasource": "$datasource", + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 39 + }, + "heatmap": { }, + "hideZeroBuckets": true, + "highlightCards": true, + "id": 98, + "legend": { + "show": true + }, + "panels": [ ], + "reverseYBuckets": false, + "targets": [ + { + "expr": "sum by (le) (rate(loki_ingester_chunk_utilization_bucket{cluster=\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"}[1m]))", + "format": "heatmap", + "instant": false, + "interval": "", + "legendFormat": "{{ le }}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Chunk Utilization", + "tooltip": { + "show": true, + "showHistogram": false + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "xBucketNumber": null, + "xBucketSize": null, + "yAxis": { + "decimals": 0, + "format": "percentunit", + "logBase": 1, + "max": null, + "min": null, + "show": true, + "splitFactor": null + }, + "yBucketBound": "auto", + "yBucketNumber": null, + "yBucketSize": null + } + ], + "targets": [ ], + "title": "Chunks", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 31 + }, + "id": 64, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 32 + }, + "hiddenSeries": false, + "id": 68, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"(loki|enterprise-logs)-read.*\"}", + "intervalFactor": 3, + "legendFormat": "{{pod}}-{{container}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "CPU Usage", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 39 + }, + "hiddenSeries": false, + "id": 69, + "legend": { + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "go_memstats_heap_inuse_bytes{cluster=\"$cluster\", namespace=\"$namespace\", pod=~\"(loki|enterprise-logs)-read.*\"}", + "instant": false, + "intervalFactor": 3, + "legendFormat": "{{pod}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Memory Usage", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$logs", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 3, + "w": 18, + "x": 12, + "y": 32 + }, + "hiddenSeries": false, + "id": 65, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "{}", + "color": "#F2495C" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate({cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\"} | logfmt | level=\"error\"[1m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Error Log Rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": false, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "$logs", + "gridPos": { + "h": 18, + "w": 18, + "x": 12, + "y": 35 + }, + "id": 66, + "options": { + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": true + }, + "panels": [ ], + "targets": [ + { + "expr": "{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\"} | logfmt | level=\"error\"", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Logs", + "type": "logs" + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 46 + }, + "hiddenSeries": false, + "id": 70, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\", status_code!~\"5[0-9]{2}\"}[1m])) by (route)\n/\nsum(rate(loki_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", job=~\"($namespace)/(loki|enterprise-logs)-read\"}[1m])) by (route)", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{route}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Success Rate", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Read Path", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 32 + }, + "id": 52, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 30 + }, + "hiddenSeries": false, + "id": 53, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_memcache_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (method, name, le, container))", + "intervalFactor": 1, + "legendFormat": "{{container}}: .99-{{method}}-{{name}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_memcache_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (method, name, le, container))", + "hide": false, + "legendFormat": "{{container}}: .9-{{method}}-{{name}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_memcache_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (method, name, le, container))", + "hide": false, + "legendFormat": "{{container}}: .5-{{method}}-{{name}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 38 + }, + "hiddenSeries": false, + "id": 54, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_memcache_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, method, name, container)", + "intervalFactor": 1, + "legendFormat": "{{container}}: {{status_code}}-{{method}}-{{name}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Memcached", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 33 + }, + "id": 57, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 31 + }, + "hiddenSeries": false, + "id": 55, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_consul_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".99-{{operation}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_consul_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".9-{{operation}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_consul_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".5-{{operation}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 39 + }, + "hiddenSeries": false, + "id": 58, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_consul_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, status_code, method)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}-{{operation}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Consul", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 34 + }, + "id": 43, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 9 + }, + "hiddenSeries": false, + "id": 41, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/MutateRows\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".9", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/MutateRows\"}[5m])) by (operation, le))", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/MutateRows\"}[5m])) by (operation, le))", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "MutateRows Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 9 + }, + "hiddenSeries": false, + "id": 46, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/ReadRows\"}[5m])) by (operation, le))", + "interval": "", + "intervalFactor": 1, + "legendFormat": "99%", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/ReadRows\"}[5m])) by (operation, le))", + "interval": "", + "legendFormat": "90%", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/ReadRows\"}[5m])) by (operation, le))", + "interval": "", + "legendFormat": "50%", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "ReadRows Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 9 + }, + "hiddenSeries": false, + "id": 44, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable\"}[5m])) by (operation, le))", + "interval": "", + "intervalFactor": 1, + "legendFormat": "99%", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable\"}[5m])) by (operation, le))", + "interval": "", + "legendFormat": "90%", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable\"}[5m])) by (operation, le))", + "interval": "", + "legendFormat": "50%", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "GetTable Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 9 + }, + "hiddenSeries": false, + "id": 45, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".9", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables\"}[5m])) by (operation, le))", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_bigtable_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables\"}[5m])) by (operation, le))", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "ListTables Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 16 + }, + "hiddenSeries": false, + "id": 47, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_bigtable_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/MutateRows\"}[5m])) by (status_code)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "MutateRows Status", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 16 + }, + "hiddenSeries": false, + "id": 50, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_bigtable_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.v2.Bigtable/ReadRows\"}[5m])) by (status_code)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "ReadRows Status", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 16 + }, + "hiddenSeries": false, + "id": 48, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_bigtable_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable\"}[5m])) by (status_code)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "GetTable Status", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 16 + }, + "hiddenSeries": false, + "id": 49, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_bigtable_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\", operation=\"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables\"}[5m])) by (status_code)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "ListTables Status", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Big Table", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 35 + }, + "id": 60, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 33 + }, + "hiddenSeries": false, + "id": 61, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_gcs_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".99-{{operation}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_gcs_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".9-{{operation}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_gcs_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".5-{{operation}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 41 + }, + "hiddenSeries": false, + "id": 62, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_gcs_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}-{{operation}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "GCS", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 36 + }, + "id": 76, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 9 + }, + "id": 82, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(cortex_dynamo_failures_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Failure Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 9 + }, + "id": 83, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(cortex_dynamo_consumed_capacity_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Consumed Capacity Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 9 + }, + "id": 84, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(cortex_dynamo_throttled_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Throttled Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 9 + }, + "id": 85, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(cortex_dynamo_dropped_requests_total{cluster=\"$cluster\", namespace=\"$namespace\"}[5m]))", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Dropped Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 15 + }, + "id": 86, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(cortex_dynamo_query_pages_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])))", + "legendFormat": ".99", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(cortex_dynamo_query_pages_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])))", + "legendFormat": ".9", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(cortex_dynamo_query_pages_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])))", + "legendFormat": ".5", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Query Pages", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 9, + "x": 6, + "y": 15 + }, + "id": 87, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(cortex_dynamo_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".99-{{operation}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(cortex_dynamo_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".9-{{operation}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(cortex_dynamo_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".5-{{operation}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 9, + "x": 15, + "y": 15 + }, + "id": 88, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(cortex_dynamo_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}-{{operation}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Dynamo", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 37 + }, + "id": 78, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 79, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_s3_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".99-{{operation}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_s3_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".9-{{operation}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_s3_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".5-{{operation}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 80, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_s3_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}-{{operation}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "S3", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 37 + }, + "id": 78, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 79, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_azure_blob_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".99-{{operation}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_azure_blob_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".9-{{operation}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_azure_blob_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".5-{{operation}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 80, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_azure_blob_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}-{{operation}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "Azure Blob", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 37 + }, + "id": 114, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 115, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(.99, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "intervalFactor": 1, + "legendFormat": ".99-{{operation}}", + "refId": "A" + }, + { + "expr": "histogram_quantile(.9, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".9-{{operation}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(.5, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (operation, le))", + "hide": false, + "legendFormat": ".5-{{operation}}", + "refId": "C" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Latency By Operation", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 116, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [ ] + }, + "panels": [ ], + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=\"$cluster\", namespace=\"$namespace\"}[5m])) by (status_code, operation)", + "intervalFactor": 1, + "legendFormat": "{{status_code}}-{{operation}}", + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeRegions": [ ], + "timeShift": null, + "title": "Status By Method", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "targets": [ ], + "title": "BoltDB Shipper", + "type": "row" + } + ], + "refresh": "10s", + "rows": [ ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "hide": 0, + "label": null, + "name": "logs", + "options": [ ], + "query": "loki", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Operational", + "uid": "operational", + "version": 0 + } diff --git a/charts/mayastor/charts/loki/src/dashboards/loki-reads-resources.json b/charts/mayastor/charts/loki/src/dashboards/loki-reads-resources.json new file mode 100644 index 0000000..6fa166f --- /dev/null +++ b/charts/mayastor/charts/loki/src/dashboards/loki-reads-resources.json @@ -0,0 +1,964 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_cpu_quota{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"} / container_spec_cpu_period{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "CPU", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_memory_limit_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"} > 0)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (workingset)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (go_memstats_heap_inuse_bytes{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-read\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (go heap inuse)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "gridPos": { }, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(instance, pod, device) (rate(node_disk_written_bytes_total[$__rate_interval])) + ignoring(pod) group_right() (label_replace(count by(instance, pod, device) (container_fs_writes_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\", device!~\".*sda.*\"}), \"device\", \"$1\", \"device\", \"/dev/(.*)\") * 0)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}} - {{device}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Writes", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "gridPos": { }, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(instance, pod, device) (rate(node_disk_read_bytes_total[$__rate_interval])) + ignoring(pod) group_right() (label_replace(count by(instance, pod, device) (container_fs_writes_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\", device!~\".*sda.*\"}), \"device\", \"$1\", \"device\", \"/dev/(.*)\") * 0)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}} - {{device}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Reads", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max by(persistentvolumeclaim) (kubelet_volume_stats_used_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\"} / kubelet_volume_stats_capacity_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\"}) and count by(persistentvolumeclaim) (kube_persistentvolumeclaim_labels{cluster=~\"$cluster\", namespace=~\"$namespace\",label_name=~\"(loki|enterprise-logs)-read.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{persistentvolumeclaim}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Space Utilization", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "loki_boltdb_shipper_query_readiness_duration_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "duration", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Query Readiness Duration", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Read path", + "titleSize": "h6", + "type": "row" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_cpu_quota{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"} / container_spec_cpu_period{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "CPU", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 9, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_memory_limit_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"} > 0)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (workingset)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (go_memstats_heap_inuse_bytes{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (go heap inuse)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Ingester", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Reads Resources", + "uid": "reads-resources", + "version": 0 + } \ No newline at end of file diff --git a/charts/mayastor/charts/loki/src/dashboards/loki-reads.json b/charts/mayastor/charts/loki/src/dashboards/loki-reads.json new file mode 100644 index 0000000..6cae30f --- /dev/null +++ b/charts/mayastor/charts/loki/src/dashboards/loki-reads.json @@ -0,0 +1,504 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + "1xx": "#EAB839", + "2xx": "#7EB26D", + "3xx": "#6ED0E0", + "4xx": "#EF843C", + "5xx": "#E24D42", + "error": "#E24D42", + "success": "#7EB26D" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{status}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "QPS", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\", cluster=~\"$cluster\"})) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ route }} 99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum by (le,route) (job_route:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\", cluster=~\"$cluster\"})) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ route }} 50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "1e3 * sum(job_route:loki_request_duration_seconds_sum:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\", cluster=~\"$cluster\"}) by (route) / sum(job_route:loki_request_duration_seconds_count:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-read\", route=~\"loki_api_v1_series|api_prom_series|api_prom_query|api_prom_label|api_prom_label_name_values|loki_api_v1_query|loki_api_v1_query_range|loki_api_v1_labels|loki_api_v1_label_name_values\", cluster=~\"$cluster\"}) by (route) ", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ route }} Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Read Path", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + "1xx": "#EAB839", + "2xx": "#7EB26D", + "3xx": "#6ED0E0", + "4xx": "#EF843C", + "5xx": "#E24D42", + "error": "#E24D42", + "success": "#7EB26D" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{status}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "QPS", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_boltdb_shipper_request_duration_seconds_sum{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-read\", operation=\"Shipper.Query\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "BoltDB Shipper", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Reads", + "uid": "reads", + "version": 0 + } \ No newline at end of file diff --git a/charts/mayastor/charts/loki/src/dashboards/loki-retention.json b/charts/mayastor/charts/loki/src/dashboards/loki-retention.json new file mode 100644 index 0000000..7fc99ec --- /dev/null +++ b/charts/mayastor/charts/loki/src/dashboards/loki-retention.json @@ -0,0 +1,1537 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_cpu_quota{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"} / container_spec_cpu_period{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "CPU", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_memory_limit_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-read.*\"} > 0)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (workingset)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (go_memstats_heap_inuse_bytes{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-read\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (go heap inuse)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Resource Usage", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "fixed" + }, + "custom": { }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "dateTimeFromNow" + } + }, + "fill": 1, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": { }, + "textMode": "auto" + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "loki_boltdb_shipper_compact_tables_operation_last_successful_run_timestamp_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\"} * 1e3", + "format": "time_series", + "instant": true, + "refId": "A" + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Last Compact and Mark Operation Success", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "stat", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "loki_boltdb_shipper_compact_tables_operation_duration_seconds{cluster=~\"$cluster\", namespace=~\"$namespace\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "duration", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Compact and Mark Operations Duration", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status)(rate(loki_boltdb_shipper_compact_tables_operation_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{success}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Compact and Mark Operations Per Status", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Compact and Mark", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "count by(action)(loki_boltdb_shipper_retention_marker_table_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{action}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Processed Tables Per Action", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "count by(table,action)(loki_boltdb_shipper_retention_marker_table_processed_total{cluster=~\"$cluster\", namespace=~\"$namespace\" , action=~\"modified|deleted\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{table}}-{{action}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Modified Tables", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 9, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (table)(rate(loki_boltdb_shipper_retention_marker_count_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) >0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{table}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Marks Creation Rate Per Table", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Per Table Marker", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "format": "short", + "id": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (increase(loki_boltdb_shipper_retention_marker_count_total{cluster=~\"$cluster\", namespace=~\"$namespace\"}[24h]))", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Marked Chunks (24h)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "singlestat", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 11, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_retention_marker_table_processed_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_retention_marker_table_processed_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_boltdb_shipper_retention_marker_table_processed_duration_seconds_sum{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_retention_marker_table_processed_duration_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Mark Table Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "format": "short", + "id": 12, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (increase(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\"}[24h]))", + "format": "time_series", + "instant": true, + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "70,80", + "timeFrom": null, + "timeShift": null, + "title": "Delete Chunks (24h)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "singlestat", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 13, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_bucket{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_sum{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Delete Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Sweeper", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "time() - (loki_boltdb_shipper_retention_sweeper_marker_file_processing_current_time{cluster=~\"$cluster\", namespace=~\"$namespace\"} > 0)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "lag", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Sweeper Lag", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 15, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(loki_boltdb_shipper_retention_sweeper_marker_files_current{cluster=~\"$cluster\", namespace=~\"$namespace\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "count", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Marks Files to Process", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 16, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status)(rate(loki_boltdb_shipper_retention_sweeper_chunk_deleted_duration_seconds_count{cluster=~\"$cluster\", namespace=~\"$namespace\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{status}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Delete Rate Per Status", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "datasource": "$logs", + "id": 17, + "span": 12, + "targets": [ + { + "expr": "{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-read\"}", + "refId": "A" + } + ], + "title": "Compactor Logs", + "type": "logs" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Logs", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "hide": 0, + "label": null, + "name": "logs", + "options": [ ], + "query": "loki", + "refresh": 1, + "regex": "", + "type": "datasource" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Retention", + "uid": "retention", + "version": 0 + } \ No newline at end of file diff --git a/charts/mayastor/charts/loki/src/dashboards/loki-writes-resources.json b/charts/mayastor/charts/loki/src/dashboards/loki-writes-resources.json new file mode 100644 index 0000000..1b68bd3 --- /dev/null +++ b/charts/mayastor/charts/loki/src/dashboards/loki-writes-resources.json @@ -0,0 +1,700 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "collapsed": false, + "panels": [ + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (loki_ingester_memory_streams{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "In-memory streams", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (rate(container_cpu_usage_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_cpu_quota{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"} / container_spec_cpu_period{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "CPU", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "limit", + "color": "#E02F44", + "fill": 0 + } + ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max by(pod) (container_memory_working_set_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + }, + { + "expr": "min(container_spec_memory_limit_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\"} > 0)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "limit", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (workingset)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(pod) (go_memstats_heap_inuse_bytes{cluster=~\"$cluster\", job=~\"($namespace)/(loki|enterprise-logs)-write\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (go heap inuse)", + "tooltip": { + "sort": 2 + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "gridPos": { }, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(instance, pod, device) (rate(node_disk_written_bytes_total[$__rate_interval])) + ignoring(pod) group_right() (label_replace(count by(instance, pod, device) (container_fs_writes_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\", device!~\".*sda.*\"}), \"device\", \"$1\", \"device\", \"/dev/(.*)\") * 0)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}} - {{device}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Writes", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "gridPos": { }, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by(instance, pod, device) (rate(node_disk_read_bytes_total[$__rate_interval])) + ignoring(pod) group_right() (label_replace(count by(instance, pod, device) (container_fs_writes_bytes_total{cluster=~\"$cluster\", namespace=~\"$namespace\", container=\"loki\", pod=~\"(loki|enterprise-logs)-write.*\", device!~\".*sda.*\"}), \"device\", \"$1\", \"device\", \"/dev/(.*)\") * 0)\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{pod}} - {{device}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Reads", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "gridPos": { }, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max by(persistentvolumeclaim) (kubelet_volume_stats_used_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\"} / kubelet_volume_stats_capacity_bytes{cluster=~\"$cluster\", namespace=~\"$namespace\"}) and count by(persistentvolumeclaim) (kube_persistentvolumeclaim_labels{cluster=~\"$cluster\", namespace=~\"$namespace\",label_name=~\"(loki|enterprise-logs)-write.*\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{persistentvolumeclaim}}", + "legendLink": null, + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Space Utilization", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Write path", + "titleSize": "h6", + "type": "row" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Writes Resources", + "uid": "writes-resources", + "version": 0 + } \ No newline at end of file diff --git a/charts/mayastor/charts/loki/src/dashboards/loki-writes.json b/charts/mayastor/charts/loki/src/dashboards/loki-writes.json new file mode 100644 index 0000000..ebaf33e --- /dev/null +++ b/charts/mayastor/charts/loki/src/dashboards/loki-writes.json @@ -0,0 +1,504 @@ +{ + "annotations": { + "list": [ ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "hideControls": false, + "links": [ + { + "asDropdown": true, + "icon": "external link", + "includeVars": true, + "keepTime": true, + "tags": [ + "loki" + ], + "targetBlank": false, + "title": "Loki Dashboards", + "type": "dashboards" + } + ], + "refresh": "10s", + "rows": [ + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + "1xx": "#EAB839", + "2xx": "#7EB26D", + "3xx": "#6ED0E0", + "4xx": "#EF843C", + "5xx": "#E24D42", + "error": "#E24D42", + "success": "#7EB26D" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", route=~\"api_prom_push|loki_api_v1_push|/httpgrpc.HTTP/Handle\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{status}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "QPS", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum by (le) (job:loki_request_duration_seconds_bucket:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "1e3 * sum(job:loki_request_duration_seconds_sum:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"}) / sum(job:loki_request_duration_seconds_count:sum_rate{job=~\"($namespace)/(loki|enterprise-logs)-write\", cluster=~\"$cluster\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Write Path", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "aliasColors": { + "1xx": "#EAB839", + "2xx": "#7EB26D", + "3xx": "#6ED0E0", + "4xx": "#EF843C", + "5xx": "#E24D42", + "error": "#E24D42", + "success": "#7EB26D" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 10, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (status) (\n label_replace(label_replace(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval]),\n \"status\", \"${1}xx\", \"status_code\", \"([0-9])..\"),\n \"status\", \"${1}\", \"status_code\", \"([a-z]+)\"))\n", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{status}}", + "refId": "A", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "QPS", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + }, + { + "aliasColors": { }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ ], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ ], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "99th Percentile", + "refId": "A", + "step": 10 + }, + { + "expr": "histogram_quantile(0.50, sum(rate(loki_boltdb_shipper_request_duration_seconds_bucket{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval])) by (le)) * 1e3", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "50th Percentile", + "refId": "B", + "step": 10 + }, + { + "expr": "sum(rate(loki_boltdb_shipper_request_duration_seconds_sum{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval])) * 1e3 / sum(rate(loki_boltdb_shipper_request_duration_seconds_count{cluster=~\"$cluster\",job=~\"($namespace)/(loki|enterprise-logs)-write\", operation=\"WRITE\"}[$__rate_interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average", + "refId": "C", + "step": 10 + } + ], + "thresholds": [ ], + "timeFrom": null, + "timeShift": null, + "title": "Latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ ] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "BoltDB Shipper", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "loki" + ], + "templating": { + "list": [ + { + "current": { + "text": "default", + "value": "default" + }, + "hide": 0, + "label": "Data Source", + "name": "datasource", + "options": [ ], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "cluster", + "multi": false, + "name": "cluster", + "options": [ ], + "query": "label_values(loki_build_info, cluster)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "text": "prod", + "value": "prod" + }, + "datasource": "$datasource", + "hide": 0, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [ ], + "query": "label_values(loki_build_info{cluster=~\"$cluster\"}, namespace)", + "refresh": 1, + "regex": "", + "sort": 2, + "tagValuesQuery": "", + "tags": [ ], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "utc", + "title": "Loki / Writes", + "uid": "writes", + "version": 0 + } \ No newline at end of file diff --git a/charts/mayastor/charts/loki/src/helm-test/Dockerfile b/charts/mayastor/charts/loki/src/helm-test/Dockerfile new file mode 100644 index 0000000..c831329 --- /dev/null +++ b/charts/mayastor/charts/loki/src/helm-test/Dockerfile @@ -0,0 +1,13 @@ +ARG GO_VERSION=1.24 +FROM golang:${GO_VERSION} as build + +# build via Makefile target helm-test-image in root +# Makefile. Building from this directory will not be +# able to access source needed in rest of repo. +COPY . /src/loki +WORKDIR /src/loki +RUN make clean && make BUILD_IN_CONTAINER=false helm-test + +FROM gcr.io/distroless/static:debug +COPY --from=build /src/loki/production/helm/loki/src/helm-test/helm-test /usr/bin/helm-test +ENTRYPOINT [ "/usr/bin/helm-test" ] diff --git a/charts/mayastor/charts/loki/src/helm-test/README.md b/charts/mayastor/charts/loki/src/helm-test/README.md new file mode 100644 index 0000000..68c9bfd --- /dev/null +++ b/charts/mayastor/charts/loki/src/helm-test/README.md @@ -0,0 +1,7 @@ +# Loki Helm Test + +This folder contains a collection of go tests that test if a Loki canary is running correctly. It's primary use it to test that the helm chart is working correctly by using metrics from the Loki canary. In the helm chart, the template for this test is only available if you are running both the Loki canary and have self monitoring enabled (as the Loki canary's logs need to be in Loki for it to work). However, the tests in this folder can be run against any running Loki canary using `go test`. + +## Instructions + +Run `go test .` from this directory, or use the Docker image published at `grafana/loki-helm-test`. diff --git a/charts/mayastor/charts/loki/src/helm-test/canary_test.go b/charts/mayastor/charts/loki/src/helm-test/canary_test.go new file mode 100644 index 0000000..002cae4 --- /dev/null +++ b/charts/mayastor/charts/loki/src/helm-test/canary_test.go @@ -0,0 +1,178 @@ +//go:build helm_test +// +build helm_test + +package test + +import ( + "context" + "errors" + "fmt" + "io" + "net/http" + "os" + "testing" + "time" + + "github.com/prometheus/client_golang/api" + v1 "github.com/prometheus/client_golang/api/prometheus/v1" + promConfig "github.com/prometheus/common/config" + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/model/labels" + "github.com/prometheus/prometheus/model/textparse" + "github.com/stretchr/testify/require" +) + +type testResultFunc func(t *testing.T, ctx context.Context, metric string, test func(model.SampleValue) bool, msg string) error + +func TestCanary(t *testing.T) { + + var testResult testResultFunc + + // Default to directly querying a canary and looking for specific metrics. + testResult = testResultCanary + totalEntries := "loki_canary_entries_total" + totalEntriesMissing := "loki_canary_missing_entries_total" + + // For backwards compatibility and also for anyone who wants to validate with prometheus instead of querying + // a canary directly, if the CANARY_PROMETHEUS_ADDRESS is specified we will use prometheus to validate. + address := os.Getenv("CANARY_PROMETHEUS_ADDRESS") + if address != "" { + testResult = testResultPrometheus + // Use the sum function to aggregate the results from multiple canaries. + totalEntries = "sum(loki_canary_entries_total)" + totalEntriesMissing = "sum(loki_canary_missing_entries_total)" + } + + timeout := getEnv("CANARY_TEST_TIMEOUT", "1m") + timeoutDuration, err := time.ParseDuration(timeout) + require.NoError(t, err, "Failed to parse timeout. Please set CANARY_TEST_TIMEOUT to a valid duration.") + + ctx, cancel := context.WithTimeout(context.Background(), timeoutDuration) + + t.Cleanup(func() { + cancel() + }) + + t.Run("Canary should have entries", func(t *testing.T) { + eventually(t, func() error { + return testResult(t, ctx, totalEntries, func(v model.SampleValue) bool { + return v > 0 + }, fmt.Sprintf("Expected %s to be greater than 0", totalEntries)) + }, timeoutDuration, "Expected Loki Canary to have entries") + }) + + t.Run("Canary should not have missed any entries", func(t *testing.T) { + eventually(t, func() error { + return testResult(t, ctx, totalEntriesMissing, func(v model.SampleValue) bool { + return v == 0 + }, fmt.Sprintf("Expected %s to equal 0", totalEntriesMissing)) + }, timeoutDuration, "Expected Loki Canary to not have any missing entries") + }) +} + +func getEnv(key, fallback string) string { + if value, ok := os.LookupEnv(key); ok { + return value + } + return fallback +} + +func testResultPrometheus(t *testing.T, ctx context.Context, query string, test func(model.SampleValue) bool, msg string) error { + // TODO (ewelch): if we did a lot of these, we'd want to reuse the client but right now we only run a couple tests + client := newClient(t) + result, _, err := client.Query(ctx, query, time.Now()) + if err != nil { + return err + } + if v, ok := result.(model.Vector); ok { + for _, s := range v { + t.Logf("%s => %v\n", query, s.Value) + if !test(s.Value) { + return errors.New(msg) + } + } + return nil + } + + return fmt.Errorf("unexpected Prometheus result type: %v ", result.Type()) +} + +func newClient(t *testing.T) v1.API { + address := os.Getenv("CANARY_PROMETHEUS_ADDRESS") + require.NotEmpty(t, address, "CANARY_PROMETHEUS_ADDRESS must be set to a valid prometheus address") + + client, err := api.NewClient(api.Config{ + Address: address, + }) + require.NoError(t, err, "Failed to create Loki Canary client") + + return v1.NewAPI(client) +} + +func testResultCanary(t *testing.T, ctx context.Context, metric string, test func(model.SampleValue) bool, msg string) error { + address := os.Getenv("CANARY_SERVICE_ADDRESS") + require.NotEmpty(t, address, "CANARY_SERVICE_ADDRESS must be set to a valid kubernetes service for the Loki canaries") + + // TODO (ewelch): if we did a lot of these, we'd want to reuse the client but right now we only run a couple tests + client, err := promConfig.NewClientFromConfig(promConfig.HTTPClientConfig{}, "canary-test") + require.NoError(t, err, "Failed to create Prometheus client") + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, address, nil) + require.NoError(t, err, "Failed to create request") + + rsp, err := client.Do(req) + if rsp != nil { + defer rsp.Body.Close() + } + require.NoError(t, err, "Failed to scrape metrics") + + body, err := io.ReadAll(rsp.Body) + require.NoError(t, err, "Failed to read response body") + + p, err := textparse.New(body, rsp.Header.Get("Content-Type"), true, nil) + require.NoError(t, err, "Failed to create Prometheus parser") + + for { + e, err := p.Next() + if err == io.EOF { + return errors.New("metric not found") + } + + if e != textparse.EntrySeries { + continue + } + + l := labels.Labels{} + p.Metric(&l) + + // Currently we aren't validating any labels, just the metric name, however this could be extended to do so. + name := l.Get(model.MetricNameLabel) + if name != metric { + continue + } + + _, _, val := p.Series() + t.Logf("%s => %v\n", metric, val) + + // Note: SampleValue has functions for comparing the equality of two floats which is + // why we convert this back to a SampleValue here for easier use intests. + if !test(model.SampleValue(val)) { + return errors.New(msg) + } + + // Returning here will only validate that one series was found matching the label name that met the condition + // it could be possible since we don't validate the rest of the labels that there is mulitple series + // but currently this meets the spirit of the test. + return nil + } +} + +func eventually(t *testing.T, test func() error, timeoutDuration time.Duration, msg string) { + require.Eventually(t, func() bool { + queryError := test() + if queryError != nil { + t.Logf("Query failed\n%+v\n", queryError) + } + return queryError == nil + }, timeoutDuration, 1*time.Second, msg) +} diff --git a/charts/mayastor/charts/loki/src/helm-test/default.nix b/charts/mayastor/charts/loki/src/helm-test/default.nix new file mode 100644 index 0000000..a129b23 --- /dev/null +++ b/charts/mayastor/charts/loki/src/helm-test/default.nix @@ -0,0 +1,27 @@ +{ pkgs, lib, buildGoModule, dockerTools, rev }: +rec { + loki-helm-test = buildGoModule rec { + pname = "loki-helm-test"; + version = "0.1.0"; + + src = ./../../../../..; + vendorHash = null; + + buildPhase = '' + runHook preBuild + go test --tags=helm_test -c -o $out/bin/helm-test ./production/helm/loki/src/helm-test + runHook postBuild + ''; + + doCheck = false; + }; + + # by default, uses the nix hash as the tag, which can be retrieved with: + # basename "$(readlink result)" | cut -d - -f 1 + loki-helm-test-docker = dockerTools.buildImage { + name = "grafana/loki-helm-test"; + config = { + Entrypoint = [ "${loki-helm-test}/bin/helm-test" ]; + }; + }; +} diff --git a/charts/mayastor/charts/loki/src/rules.yaml.tpl b/charts/mayastor/charts/loki/src/rules.yaml.tpl new file mode 100644 index 0000000..840401d --- /dev/null +++ b/charts/mayastor/charts/loki/src/rules.yaml.tpl @@ -0,0 +1,86 @@ +--- +groups: + - name: "loki_rules" + rules: + - expr: histogram_quantile(0.99, sum(rate(loki_request_duration_seconds_bucket[1m])) + by (le, job)) + record: job:loki_request_duration_seconds:99quantile + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: histogram_quantile(0.50, sum(rate(loki_request_duration_seconds_bucket[1m])) + by (le, job)) + record: job:loki_request_duration_seconds:50quantile + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (job) / sum(rate(loki_request_duration_seconds_count[1m])) + by (job) + record: job:loki_request_duration_seconds:avg + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job) + record: job:loki_request_duration_seconds_bucket:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (job) + record: job:loki_request_duration_seconds_sum:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_count[1m])) by (job) + record: job:loki_request_duration_seconds_count:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: histogram_quantile(0.99, sum(rate(loki_request_duration_seconds_bucket[1m])) + by (le, job, route)) + record: job_route:loki_request_duration_seconds:99quantile + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: histogram_quantile(0.50, sum(rate(loki_request_duration_seconds_bucket[1m])) + by (le, job, route)) + record: job_route:loki_request_duration_seconds:50quantile + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (job, route) / sum(rate(loki_request_duration_seconds_count[1m])) + by (job, route) + record: job_route:loki_request_duration_seconds:avg + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job, route) + record: job_route:loki_request_duration_seconds_bucket:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (job, route) + record: job_route:loki_request_duration_seconds_sum:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_count[1m])) by (job, route) + record: job_route:loki_request_duration_seconds_count:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: histogram_quantile(0.99, sum(rate(loki_request_duration_seconds_bucket[1m])) + by (le, namespace, job, route)) + record: namespace_job_route:loki_request_duration_seconds:99quantile + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: histogram_quantile(0.50, sum(rate(loki_request_duration_seconds_bucket[1m])) + by (le, namespace, job, route)) + record: namespace_job_route:loki_request_duration_seconds:50quantile + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (namespace, job, route) + / sum(rate(loki_request_duration_seconds_count[1m])) by (namespace, job, route) + record: namespace_job_route:loki_request_duration_seconds:avg + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, namespace, job, + route) + record: namespace_job_route:loki_request_duration_seconds_bucket:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_sum[1m])) by (namespace, job, route) + record: namespace_job_route:loki_request_duration_seconds_sum:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" + - expr: sum(rate(loki_request_duration_seconds_count[1m])) by (namespace, job, route) + record: namespace_job_route:loki_request_duration_seconds_count:sum_rate + labels: + cluster: "{{ include "loki.clusterLabel" $ }}" diff --git a/charts/mayastor/charts/loki/templates/NOTES.txt b/charts/mayastor/charts/loki/templates/NOTES.txt new file mode 100644 index 0000000..336a354 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/NOTES.txt @@ -0,0 +1,184 @@ +*********************************************************************** + Welcome to Grafana Loki + Chart version: {{ .Chart.Version }} + Chart Name: {{ .Chart.Name }} + Loki version: {{ .Chart.AppVersion }} +*********************************************************************** + +** Please be patient while the chart is being deployed ** + +Tip: + + Watch the deployment status using the command: kubectl get pods -w --namespace {{ $.Release.Namespace }} + +If pods are taking too long to schedule make sure pod affinity can be fulfilled in the current cluster. + +*********************************************************************** +Installed components: +*********************************************************************** + +{{- if .Values.monitoring.selfMonitoring.enabled }} +* grafana-agent-operator +{{- end }} +{{- if eq (include "loki.deployment.isSingleBinary" .) "true" }} +* loki +{{- else -}} +{{- if .Values.gateway.enabled }} +* gateway +{{- end }} +{{- if .Values.minio.enabled }} +* minio +{{- end }} +{{- if eq (include "loki.deployment.isScalable" .) "true" }} +* read +* write +{{- if not .Values.read.legacyReadTarget }} +* backend +{{- end }} +{{- else }} +* compactor +* index gateway +* query scheduler +* ruler +* distributor +* ingester +* querier +* query frontend +{{- end }} +{{- end }} + + +{{- if eq (include "loki.deployment.isSingleBinary" .) "true" }} + +Loki has been deployed as a single binary. +This means a single pod is handling reads and writes. You can scale that pod vertically by adding more CPU and memory resources. + +{{- end }} + + +*********************************************************************** +Sending logs to Loki +*********************************************************************** + +{{- if .Values.gateway.enabled }} + +Loki has been configured with a gateway (nginx) to support reads and writes from a single component. + +{{- end }} + +You can send logs from inside the cluster using the cluster DNS: + +{{- if .Values.gateway.enabled }} + +http://{{ include "loki.gatewayFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}/loki/api/v1/push + +{{- else }} +{{- if eq (include "loki.deployment.isSingleBinary" .) "true" }} + +http://{{ include "loki.singleBinaryFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:{{ .Values.loki.server.http_listen_port }}/loki/api/v1/push + +{{- end}} +{{- if eq (include "loki.deployment.isScalable" .) "true" }} + +http://{{ include "loki.writeFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:{{ .Values.loki.server.http_listen_port }}/loki/api/v1/push + +{{- end }} +{{- if eq (include "loki.deployment.isDistributed" .) "true" }} + +http://{{ include "loki.distributorFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:3100/loki/api/v1/push + +{{- end }} +{{- end }} + +You can test to send data from outside the cluster by port-forwarding the gateway to your local machine: +{{- if .Values.gateway.enabled }} + + kubectl port-forward --namespace {{ $.Release.Namespace }} svc/{{ include "loki.gatewayFullname" . }} 3100:{{ .Values.gateway.service.port }} & + +{{- else }} +{{- if eq (include "loki.deployment.isSingleBinary" .) "true" }} + + kubectl port-forward --namespace {{ $.Release.Namespace }} svc/{{ include "loki.singleBinaryFullname" . }} 3100:{{ .Values.loki.server.http_listen_port }} & + +{{- end}} +{{- if eq (include "loki.deployment.isScalable" .) "true" }} + + kubectl port-forward --namespace {{ $.Release.Namespace }} svc/{{ include "loki.writeFullname" . }} 3100:{{ .Values.loki.server.http_listen_port }} & + +{{- end }} +{{- if eq (include "loki.deployment.isDistributed" .) "true" }} + + kubectl port-forward --namespace {{ $.Release.Namespace }} svc/{{ include "loki.distributorFullname" . }} 3100:3100 & + +{{- end }} +{{- end }} + +And then using http://127.0.0.1:3100/loki/api/v1/push URL as shown below: + +``` +curl -H "Content-Type: application/json" -XPOST -s "http://127.0.0.1:3100/loki/api/v1/push" \ +--data-raw "{\"streams\": [{\"stream\": {\"job\": \"test\"}, \"values\": [[\"$(date +%s)000000000\", \"fizzbuzz\"]]}]}" +{{- if .Values.loki.auth_enabled }} \ +-H X-Scope-OrgId:foo +{{- end}} +``` + +Then verify that Loki did receive the data using the following command: + +``` +curl "http://127.0.0.1:3100/loki/api/v1/query_range" --data-urlencode 'query={job="test"}' {{- if .Values.loki.auth_enabled }} -H X-Scope-OrgId:foo {{- end}} | jq .data.result +``` + +*********************************************************************** +Connecting Grafana to Loki +*********************************************************************** + +If Grafana operates within the cluster, you'll set up a new Loki datasource by utilizing the following URL: + +{{- if .Values.gateway.enabled }} + +http://{{ include "loki.gatewayFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}/ + +{{- else }} +{{- if eq (include "loki.deployment.isSingleBinary" .) "true" }} + +http://{{ include "loki.singleBinaryFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:{{ .Values.loki.server.http_listen_port }}/ + +{{- end}} +{{- if eq (include "loki.deployment.isScalable" .) "true" }} + +http://{{ include "loki.readFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:{{ .Values.loki.server.http_listen_port }}/ + +{{- end }} +{{- if eq (include "loki.deployment.isDistributed" .) "true" }} + +http://{{ include "loki.queryFrontendFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:3100/ + +{{- end }} +{{- end }} + + + +{{- if .Values.loki.auth_enabled }} + +*********************************************************************** +Multi-tenancy +*********************************************************************** + +Loki is configured with auth enabled (multi-tenancy) and expects tenant headers (`X-Scope-OrgID`) to be set for all API calls. + +You must configure Grafana's Loki datasource using the `HTTP Headers` section with the `X-Scope-OrgID` to target a specific tenant. +For each tenant, you can create a different datasource. + +The agent of your choice must also be configured to propagate this header. +For example, when using Promtail you can use the `tenant` stage. https://grafana.com/docs/loki/latest/send-data/promtail/stages/tenant/ + +When not provided with the `X-Scope-OrgID` while auth is enabled, Loki will reject reads and writes with a 404 status code `no org id`. + +You can also use a reverse proxy, to automatically add the `X-Scope-OrgID` header as suggested by https://grafana.com/docs/loki/latest/operations/authentication/ + +For more information, read our documentation about multi-tenancy: https://grafana.com/docs/loki/latest/operations/multi-tenancy/ + +> When using curl you can pass `X-Scope-OrgId` header using `-H X-Scope-OrgId:foo` option, where foo can be replaced with the tenant of your choice. + +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/_helpers.tpl b/charts/mayastor/charts/loki/templates/_helpers.tpl new file mode 100644 index 0000000..083d035 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/_helpers.tpl @@ -0,0 +1,1197 @@ +{{/* +Enforce valid label value. +See https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set +*/}} +{{- define "loki.validLabelValue" -}} +{{- (regexReplaceAllLiteral "[^a-zA-Z0-9._-]" . "-") | trunc 63 | trimSuffix "-" | trimSuffix "_" | trimSuffix "." }} +{{- end }} + +{{/* +Expand the name of the chart. +*/}} +{{- define "loki.name" -}} +{{- $default := ternary "enterprise-logs" "loki" .Values.enterprise.enabled }} +{{- coalesce .Values.nameOverride $default | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +singleBinary fullname +*/}} +{{- define "loki.singleBinaryFullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Resource name template +Params: + ctx = . context + component = component name (optional) + rolloutZoneName = rollout zone name (optional) +*/}} +{{- define "loki.resourceName" -}} +{{- $resourceName := include "loki.fullname" .ctx -}} +{{- if .component -}}{{- $resourceName = printf "%s-%s" $resourceName .component -}}{{- end -}} +{{- if and (not .component) .rolloutZoneName -}}{{- printf "Component name cannot be empty if rolloutZoneName (%s) is set" .rolloutZoneName | fail -}}{{- end -}} +{{- if .rolloutZoneName -}}{{- $resourceName = printf "%s-%s" $resourceName .rolloutZoneName -}}{{- end -}} +{{- if gt (len $resourceName) 253 -}}{{- printf "Resource name (%s) exceeds kubernetes limit of 253 character. To fix: shorten release name if this will be a fresh install or shorten zone names (e.g. \"a\" instead of \"zone-a\") if using zone-awareness." $resourceName | fail -}}{{- end -}} +{{- $resourceName -}} +{{- end -}} + +{{/* +Return if deployment mode is simple scalable +*/}} +{{- define "loki.deployment.isScalable" -}} + {{- and (eq (include "loki.isUsingObjectStorage" . ) "true") (or (eq .Values.deploymentMode "SingleBinary<->SimpleScalable") (eq .Values.deploymentMode "SimpleScalable") (eq .Values.deploymentMode "SimpleScalable<->Distributed")) }} +{{- end -}} + +{{/* +Return if deployment mode is single binary +*/}} +{{- define "loki.deployment.isSingleBinary" -}} + {{- or (eq .Values.deploymentMode "SingleBinary") (eq .Values.deploymentMode "SingleBinary<->SimpleScalable") }} +{{- end -}} + +{{/* +Return if deployment mode is distributed +*/}} +{{- define "loki.deployment.isDistributed" -}} + {{- and (eq (include "loki.isUsingObjectStorage" . ) "true") (or (eq .Values.deploymentMode "Distributed") (eq .Values.deploymentMode "SimpleScalable<->Distributed")) }} +{{- end -}} + + +{{/* +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 "loki.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := include "loki.name" . }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Cluster label for rules and alerts. +*/}} +{{- define "loki.clusterLabel" -}} +{{- if .Values.clusterLabelOverride }} +{{- .Values.clusterLabelOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := include "loki.name" . }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} + +{{/* Create a default storage config that uses filesystem storage +This is required for CI, but Loki will not be queryable with this default +applied, thus it is encouraged that users override this. +*/}} +{{- define "loki.storageConfig" -}} +{{- if .Values.loki.storageConfig -}} +{{- .Values.loki.storageConfig | toYaml | nindent 4 -}} +{{- else }} +{{- .Values.loki.defaultStorageConfig | toYaml | nindent 4 }} +{{- end}} +{{- end}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "loki.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "loki.labels" -}} +helm.sh/chart: {{ include "loki.chart" . }} +{{ include "loki.selectorLabels" . }} +{{- if or (.Chart.AppVersion) (.Values.loki.image.tag) }} +app.kubernetes.io/version: {{ include "loki.validLabelValue" (.Values.loki.image.tag | default .Chart.AppVersion) | quote }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "loki.selectorLabels" -}} +app.kubernetes.io/name: {{ include "loki.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "loki.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "loki.name" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Base template for building docker image reference +*/}} +{{- define "loki.baseImage" }} +{{- $registry := .global.registry | default .service.registry | default "" -}} +{{- $repository := .service.repository | default "" -}} +{{- $ref := ternary (printf ":%s" (.service.tag | default .defaultVersion | toString)) (printf "@%s" .service.digest) (empty .service.digest) -}} +{{- if and $registry $repository -}} + {{- printf "%s/%s%s" $registry $repository $ref -}} +{{- else -}} + {{- printf "%s%s%s" $registry $repository $ref -}} +{{- end -}} +{{- end -}} + +{{/* +Docker image name for Loki +*/}} +{{- define "loki.lokiImage" -}} +{{- $dict := dict "service" .Values.loki.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}} +{{- include "loki.baseImage" $dict -}} +{{- end -}} + +{{/* +Docker image name for enterprise logs +*/}} +{{- define "loki.enterpriseImage" -}} +{{- $dict := dict "service" .Values.enterprise.image "global" .Values.global.image "defaultVersion" .Values.enterprise.version -}} +{{- include "loki.baseImage" $dict -}} +{{- end -}} + +{{/* +Docker image name +*/}} +{{- define "loki.image" -}} +{{- if .Values.enterprise.enabled -}}{{- include "loki.enterpriseImage" . -}}{{- else -}}{{- include "loki.lokiImage" . -}}{{- end -}} +{{- end -}} + +{{/* +Docker image name for kubectl container +*/}} +{{- define "loki.kubectlImage" -}} +{{- $dict := dict "service" .Values.kubectlImage "global" .Values.global.image "defaultVersion" "latest" -}} +{{- include "loki.baseImage" $dict -}} +{{- end -}} + +{{/* +Generated storage config for loki common config +*/}} +{{- define "loki.commonStorageConfig" -}} +{{- if .Values.loki.storage.use_thanos_objstore -}} +object_store: + {{- include "loki.thanosStorageConfig" (dict "ctx" . "bucketName" .Values.loki.storage.bucketNames.chunks) | nindent 2 }} +{{- else }} +{{- if .Values.minio.enabled -}} +s3: + endpoint: {{ include "loki.minio" $ }} + bucketnames: chunks + secret_access_key: {{ $.Values.minio.rootPassword }} + access_key_id: {{ $.Values.minio.rootUser }} + s3forcepathstyle: true + insecure: true +{{- else if eq .Values.loki.storage.type "s3" -}} +{{- with .Values.loki.storage.s3 }} +s3: + {{- with .s3 }} + s3: {{ . }} + {{- end }} + {{- with .endpoint }} + endpoint: {{ . }} + {{- end }} + {{- with .region }} + region: {{ . }} + {{- end}} + bucketnames: {{ $.Values.loki.storage.bucketNames.chunks }} + {{- with .secretAccessKey }} + secret_access_key: {{ . }} + {{- end }} + {{- with .accessKeyId }} + access_key_id: {{ . }} + {{- end }} + {{- with .signatureVersion }} + signature_version: {{ . }} + {{- end }} + s3forcepathstyle: {{ .s3ForcePathStyle }} + insecure: {{ .insecure }} + {{- with .disable_dualstack }} + disable_dualstack: {{ . }} + {{- end }} + {{- with .http_config}} + http_config: +{{ toYaml . | indent 4 }} + {{- end }} + {{- with .backoff_config}} + backoff_config: +{{ toYaml . | indent 4 }} + {{- end }} + {{- with .sse }} + sse: +{{ toYaml . | indent 4 }} + {{- end }} +{{- end -}} + +{{- else if eq .Values.loki.storage.type "gcs" -}} +{{- with .Values.loki.storage.gcs }} +gcs: + bucket_name: {{ $.Values.loki.storage.bucketNames.chunks }} + chunk_buffer_size: {{ .chunkBufferSize }} + request_timeout: {{ .requestTimeout }} + enable_http2: {{ .enableHttp2 }} +{{- end -}} +{{- else if eq .Values.loki.storage.type "azure" -}} +{{- with .Values.loki.storage.azure }} +azure: + account_name: {{ .accountName }} + {{- with .accountKey }} + account_key: {{ . }} + {{- end }} + {{- with .connectionString }} + connection_string: {{ . }} + {{- end }} + container_name: {{ $.Values.loki.storage.bucketNames.chunks }} + use_managed_identity: {{ .useManagedIdentity }} + use_federated_token: {{ .useFederatedToken }} + {{- with .userAssignedId }} + user_assigned_id: {{ . }} + {{- end }} + {{- with .requestTimeout }} + request_timeout: {{ . }} + {{- end }} + {{- with .endpointSuffix }} + endpoint_suffix: {{ . }} + {{- end }} + {{- with .chunkDelimiter }} + chunk_delimiter: {{ . }} + {{- end }} +{{- end -}} +{{- else if eq .Values.loki.storage.type "alibabacloud" -}} +{{- with .Values.loki.storage.alibabacloud }} +alibabacloud: + bucket: {{ $.Values.loki.storage.bucketNames.chunks }} + endpoint: {{ .endpoint }} + access_key_id: {{ .accessKeyId }} + secret_access_key: {{ .secretAccessKey }} +{{- end -}} +{{- else if eq .Values.loki.storage.type "swift" -}} +{{- with .Values.loki.storage.swift }} +swift: +{{ toYaml . | indent 2 }} +{{- end -}} +{{- else -}} +{{- with .Values.loki.storage.filesystem }} +filesystem: + chunks_directory: {{ .chunks_directory }} + rules_directory: {{ .rules_directory }} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Storage config for ruler +*/}} +{{- define "loki.rulerStorageConfig" -}} +{{- if .Values.minio.enabled -}} +type: "s3" +s3: + bucketnames: ruler +{{- else if eq .Values.loki.storage.type "s3" -}} +{{- with .Values.loki.storage.s3 }} +type: "s3" +s3: + {{- with .s3 }} + s3: {{ . }} + {{- end }} + {{- with .endpoint }} + endpoint: {{ . }} + {{- end }} + {{- with .region }} + region: {{ . }} + {{- end}} + bucketnames: {{ $.Values.loki.storage.bucketNames.ruler }} + {{- with .secretAccessKey }} + secret_access_key: {{ . }} + {{- end }} + {{- with .accessKeyId }} + access_key_id: {{ . }} + {{- end }} + s3forcepathstyle: {{ .s3ForcePathStyle }} + insecure: {{ .insecure }} + {{- with .http_config }} + http_config: {{ toYaml . | nindent 6 }} + {{- end }} +{{- end -}} +{{- else if eq .Values.loki.storage.type "gcs" -}} +{{- with .Values.loki.storage.gcs }} +type: "gcs" +gcs: + bucket_name: {{ $.Values.loki.storage.bucketNames.ruler }} + chunk_buffer_size: {{ .chunkBufferSize }} + request_timeout: {{ .requestTimeout }} + enable_http2: {{ .enableHttp2 }} +{{- end -}} +{{- else if eq .Values.loki.storage.type "azure" -}} +{{- with .Values.loki.storage.azure }} +type: "azure" +azure: + account_name: {{ .accountName }} + {{- with .accountKey }} + account_key: {{ . }} + {{- end }} + {{- with .connectionString }} + connection_string: {{ . }} + {{- end }} + container_name: {{ $.Values.loki.storage.bucketNames.ruler }} + use_managed_identity: {{ .useManagedIdentity }} + use_federated_token: {{ .useFederatedToken }} + {{- with .userAssignedId }} + user_assigned_id: {{ . }} + {{- end }} + {{- with .requestTimeout }} + request_timeout: {{ . }} + {{- end }} + {{- with .endpointSuffix }} + endpoint_suffix: {{ . }} + {{- end }} +{{- end -}} +{{- else if eq .Values.loki.storage.type "swift" -}} +{{- with .Values.loki.storage.swift }} +swift: + {{- with .auth_version }} + auth_version: {{ . }} + {{- end }} + auth_url: {{ .auth_url }} + {{- with .internal }} + internal: {{ . }} + {{- end }} + username: {{ .username }} + user_domain_name: {{ .user_domain_name }} + {{- with .user_domain_id }} + user_domain_id: {{ . }} + {{- end }} + {{- with .user_id }} + user_id: {{ . }} + {{- end }} + password: {{ .password }} + {{- with .domain_id }} + domain_id: {{ . }} + {{- end }} + domain_name: {{ .domain_name }} + project_id: {{ .project_id }} + project_name: {{ .project_name }} + project_domain_id: {{ .project_domain_id }} + project_domain_name: {{ .project_domain_name }} + region_name: {{ .region_name }} + container_name: {{ .container_name }} + max_retries: {{ .max_retries | default 3 }} + connect_timeout: {{ .connect_timeout | default "10s" }} + request_timeout: {{ .request_timeout | default "5s" }} +{{- end -}} +{{- else }} +type: "local" +{{- end -}} +{{- end -}} + +{{/* Loki ruler config */}} +{{- define "loki.rulerConfig" }} +ruler: + storage: + {{- include "loki.rulerStorageConfig" . | nindent 4}} +{{- if (not (empty .Values.loki.rulerConfig)) }} +{{- toYaml .Values.loki.rulerConfig | nindent 2}} +{{- end }} +{{- end }} + +{{/* Ruler Thanos Storage Config */}} +{{- define "loki.rulerThanosStorageConfig" -}} +{{- if and .Values.loki.storage.use_thanos_objstore .Values.ruler.enabled}} + backend: {{ .Values.loki.storage.object_store.type }} + {{- include "loki.thanosStorageConfig" (dict "ctx" . "bucketName" .Values.loki.storage.bucketNames.ruler) | nindent 2 }} +{{- end }} +{{- end }} + +{{/* Enterprise Logs Admin API storage config */}} +{{- define "enterprise-logs.adminAPIStorageConfig" }} +storage: + {{- if .Values.loki.storage.use_thanos_objstore }} + backend: {{ .Values.loki.storage.object_store.type }} + {{- include "loki.thanosStorageConfig" (dict "ctx" . "bucketName" .Values.loki.storage.bucketNames.admin) | nindent 2 }} + {{- else if .Values.minio.enabled }} + backend: "s3" + s3: + bucket_name: admin + {{- else if eq .Values.loki.storage.type "s3" -}} + {{- with .Values.loki.storage.s3 }} + backend: "s3" + s3: + bucket_name: {{ $.Values.loki.storage.bucketNames.admin }} + {{- end -}} + {{- else if eq .Values.loki.storage.type "gcs" -}} + {{- with .Values.loki.storage.gcs }} + backend: "gcs" + gcs: + bucket_name: {{ $.Values.loki.storage.bucketNames.admin }} + {{- end -}} + {{- else if eq .Values.loki.storage.type "azure" -}} + {{- with .Values.loki.storage.azure }} + backend: "azure" + azure: + account_name: {{ .accountName }} + {{- with .accountKey }} + account_key: {{ . }} + {{- end }} + {{- with .connectionString }} + connection_string: {{ . }} + {{- end }} + container_name: {{ $.Values.loki.storage.bucketNames.admin }} + {{- with .endpointSuffix }} + endpoint_suffix: {{ . }} + {{- end }} + {{- end -}} + {{- else if eq .Values.loki.storage.type "swift" -}} + {{- with .Values.loki.storage.swift }} + backend: "swift" + swift: + {{- with .auth_version }} + auth_version: {{ . }} + {{- end }} + auth_url: {{ .auth_url }} + {{- with .internal }} + internal: {{ . }} + {{- end }} + username: {{ .username }} + user_domain_name: {{ .user_domain_name }} + {{- with .user_domain_id }} + user_domain_id: {{ . }} + {{- end }} + {{- with .user_id }} + user_id: {{ . }} + {{- end }} + password: {{ .password }} + {{- with .domain_id }} + domain_id: {{ . }} + {{- end }} + domain_name: {{ .domain_name }} + project_id: {{ .project_id }} + project_name: {{ .project_name }} + project_domain_id: {{ .project_domain_id }} + project_domain_name: {{ .project_domain_name }} + region_name: {{ .region_name }} + container_name: {{ .container_name }} + max_retries: {{ .max_retries | default 3 }} + connect_timeout: {{ .connect_timeout | default "10s" }} + request_timeout: {{ .request_timeout | default "5s" }} + {{- end -}} + {{- else }} + backend: "filesystem" + filesystem: + dir: {{ .Values.loki.storage.filesystem.admin_api_directory }} + {{- end -}} +{{- end }} + +{{/* +Calculate the config from structured and unstructured text input +*/}} +{{- define "loki.calculatedConfig" -}} +{{ tpl (mergeOverwrite (tpl .Values.loki.config . | fromYaml) .Values.loki.structuredConfig | toYaml) . }} +{{- end }} + +{{/* +The volume to mount for loki configuration +*/}} +{{- define "loki.configVolume" -}} +{{- if eq .Values.loki.configStorageType "Secret" -}} +secret: + secretName: {{ tpl .Values.loki.configObjectName . }} +{{- else -}} +configMap: + name: {{ tpl .Values.loki.configObjectName . }} + items: + - key: "config.yaml" + path: "config.yaml" +{{- end -}} +{{- end -}} + +{{/* +Memcached Docker image +*/}} +{{- define "loki.memcachedImage" -}} +{{- $dict := dict "service" .Values.memcached.image "global" .Values.global.image -}} +{{- include "loki.image" $dict -}} +{{- end }} + +{{/* +Memcached Exporter Docker image +*/}} +{{- define "loki.memcachedExporterImage" -}} +{{- $dict := dict "service" .Values.memcachedExporter.image "global" .Values.global.image -}} +{{- include "loki.image" $dict -}} +{{- end }} + +{{/* Allow KubeVersion to be overridden. */}} +{{- define "loki.kubeVersion" -}} + {{- default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "loki.ingress.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19-0" (include "loki.kubeVersion" .)) -}} + {{- print "networking.k8s.io/v1" -}} + {{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}} + {{- print "networking.k8s.io/v1beta1" -}} + {{- else -}} + {{- print "extensions/v1beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return if ingress is stable. +*/}} +{{- define "loki.ingress.isStable" -}} + {{- eq (include "loki.ingress.apiVersion" .) "networking.k8s.io/v1" -}} +{{- end -}} + +{{/* +Return if ingress supports ingressClassName. +*/}} +{{- define "loki.ingress.supportsIngressClassName" -}} + {{- or (eq (include "loki.ingress.isStable" .) "true") (and (eq (include "loki.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" (include "loki.kubeVersion" .))) -}} +{{- end -}} + +{{/* +Return if ingress supports pathType. +*/}} +{{- define "loki.ingress.supportsPathType" -}} + {{- or (eq (include "loki.ingress.isStable" .) "true") (and (eq (include "loki.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" (include "loki.kubeVersion" .))) -}} +{{- end -}} + +{{/* +Generate list of ingress service paths based on deployment type +*/}} +{{- define "loki.ingress.servicePaths" -}} +{{- if (eq (include "loki.deployment.isSingleBinary" .) "true") -}} +{{- include "loki.ingress.singleBinaryServicePaths" . }} +{{- else if (eq (include "loki.deployment.isDistributed" .) "true") -}} +{{- include "loki.ingress.distributedServicePaths" . }} +{{- else if and (eq (include "loki.deployment.isScalable" .) "true") (not .Values.read.legacyReadTarget ) -}} +{{- include "loki.ingress.scalableServicePaths" . }} +{{- else -}} +{{- include "loki.ingress.legacyScalableServicePaths" . }} +{{- end -}} +{{- end -}} + +{{/* +Ingress service paths for distributed deployment +*/}} +{{- define "loki.ingress.distributedServicePaths" -}} +{{- $distributorServiceName := include "loki.distributorFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $distributorServiceName "paths" .Values.ingress.paths.distributor )}} +{{- $queryFrontendServiceName := include "loki.queryFrontendFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $queryFrontendServiceName "paths" .Values.ingress.paths.queryFrontend )}} +{{- $rulerServiceName := include "loki.rulerFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $rulerServiceName "paths" .Values.ingress.paths.ruler)}} +{{- end -}} + +{{/* +Ingress service paths for legacy simple scalable deployment when backend components were part of read component. +*/}} +{{- define "loki.ingress.scalableServicePaths" -}} +{{- $readServiceName := include "loki.readFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $readServiceName "paths" .Values.ingress.paths.queryFrontend )}} +{{- $writeServiceName := include "loki.writeFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $writeServiceName "paths" .Values.ingress.paths.distributor )}} +{{- $backendServiceName := include "loki.backendFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $backendServiceName "paths" .Values.ingress.paths.ruler )}} +{{- end -}} + +{{/* +Ingress service paths for legacy simple scalable deployment +*/}} +{{- define "loki.ingress.legacyScalableServicePaths" -}} +{{- $readServiceName := include "loki.readFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $readServiceName "paths" .Values.ingress.paths.queryFrontend )}} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $readServiceName "paths" .Values.ingress.paths.ruler )}} +{{- $writeServiceName := include "loki.writeFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $writeServiceName "paths" .Values.ingress.paths.distributor )}} +{{- end -}} + +{{/* +Ingress service paths for single binary deployment +*/}} +{{- define "loki.ingress.singleBinaryServicePaths" -}} +{{- $serviceName := include "loki.singleBinaryFullname" . }} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $serviceName "paths" .Values.ingress.paths.distributor )}} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $serviceName "paths" .Values.ingress.paths.queryFrontend )}} +{{- include "loki.ingress.servicePath" (dict "ctx" . "serviceName" $serviceName "paths" .Values.ingress.paths.ruler )}} +{{- end -}} + +{{/* +Ingress service path helper function +Params: + ctx = . context + serviceName = fully qualified k8s service name + paths = list of url paths to allow ingress for +*/}} +{{- define "loki.ingress.servicePath" -}} +{{- $ingressApiIsStable := eq (include "loki.ingress.isStable" .ctx) "true" -}} +{{- $ingressSupportsPathType := eq (include "loki.ingress.supportsPathType" .ctx) "true" -}} +{{- range .paths }} +- path: {{ . }} + {{- if $ingressSupportsPathType }} + pathType: Prefix + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $.serviceName }} + port: + number: {{ $.ctx.Values.loki.server.http_listen_port }} + {{- else }} + serviceName: {{ $.serviceName }} + servicePort: {{ $.ctx.Values.loki.server.http_listen_port }} + {{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create the service endpoint including port for MinIO. +*/}} +{{- define "loki.minio" -}} +{{- if .Values.minio.enabled -}} +{{- .Values.minio.address | default (printf "%s-%s.%s.svc:%s" .Release.Name "minio" .Release.Namespace (.Values.minio.service.port | toString)) -}} +{{- end -}} +{{- end -}} + +{{/* Determine if deployment is using object storage */}} +{{- define "loki.isUsingObjectStorage" -}} +{{- or (eq .Values.loki.storage.type "gcs") (eq .Values.loki.storage.type "s3") (eq .Values.loki.storage.type "azure") (eq .Values.loki.storage.type "swift") (eq .Values.loki.storage.type "alibabacloud") -}} +{{- end -}} + +{{/* Configure the correct name for the memberlist service */}} +{{- define "loki.memberlist" -}} +{{ include "loki.name" . }}-memberlist +{{- end -}} + +{{/* Determine the public host for the Loki cluster */}} +{{- define "loki.host" -}} +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- $url := printf "%s.%s.svc.%s.:%s" (include "loki.gatewayFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.gateway.service.port | toString) }} +{{- if and $isSingleBinary (not .Values.gateway.enabled) }} + {{- $url = printf "%s.%s.svc.%s.:%s" (include "loki.singleBinaryFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} +{{- end }} +{{- printf "%s" $url -}} +{{- end -}} + +{{/* Determine the public endpoint for the Loki cluster */}} +{{- define "loki.address" -}} +{{- printf "http://%s" (include "loki.host" . ) -}} +{{- end -}} + +{{/* Name of the cluster */}} +{{- define "loki.clusterName" -}} +{{- $name := .Values.enterprise.cluster_name | default .Release.Name }} +{{- printf "%s" $name -}} +{{- end -}} + +{{/* Name of kubernetes secret to persist GEL admin token to */}} +{{- define "enterprise-logs.adminTokenSecret" }} +{{- .Values.enterprise.adminToken.secret | default (printf "%s-admin-token" (include "loki.name" . )) -}} +{{- end -}} + +{{/* Prefix for provisioned secrets created for each provisioned tenant */}} +{{- define "enterprise-logs.provisionedSecretPrefix" }} +{{- .Values.enterprise.provisioner.provisionedSecretPrefix | default (printf "%s-provisioned" (include "loki.name" . )) -}} +{{- end -}} + +{{/* Name of kubernetes secret to persist canary credentials in */}} +{{- define "enterprise-logs.selfMonitoringTenantSecret" }} +{{- .Values.enterprise.canarySecret | default (printf "%s-%s" (include "enterprise-logs.provisionedSecretPrefix" . ) .Values.monitoring.selfMonitoring.tenant.name) -}} +{{- end -}} + +{{/* Snippet for the nginx file used by gateway */}} +{{- define "loki.nginxFile" }} +worker_processes 5; ## Default: 1 +error_log /dev/stderr; +pid /tmp/nginx.pid; +worker_rlimit_nofile 8192; + +events { + worker_connections 4096; ## Default: 1024 +} + +http { + client_body_temp_path /tmp/client_temp; + proxy_temp_path /tmp/proxy_temp_path; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + client_max_body_size {{ .Values.gateway.nginxConfig.clientMaxBodySize }}; + + proxy_read_timeout 600; ## 10 minutes + proxy_send_timeout 600; + proxy_connect_timeout 600; + + proxy_http_version 1.1; + + default_type application/octet-stream; + log_format {{ .Values.gateway.nginxConfig.logFormat }} + + {{- if .Values.gateway.verboseLogging }} + access_log /dev/stderr main; + {{- else }} + + map $status $loggable { + ~^[23] 0; + default 1; + } + access_log /dev/stderr main if=$loggable; + {{- end }} + + sendfile on; + tcp_nopush on; + {{- if .Values.gateway.nginxConfig.resolver }} + resolver {{ .Values.gateway.nginxConfig.resolver }}; + {{- else }} + resolver {{ .Values.global.dnsService }}.{{ .Values.global.dnsNamespace }}.svc.{{ .Values.global.clusterDomain }}.; + {{- end }} + + {{- with .Values.gateway.nginxConfig.httpSnippet }} + {{- tpl . $ | nindent 2 }} + {{- end }} + + server { + {{- if (.Values.gateway.nginxConfig.ssl) }} + listen 8080 ssl; + {{- if .Values.gateway.nginxConfig.enableIPv6 }} + listen [::]:8080 ssl; + {{- end }} + {{- else }} + listen 8080; + {{- if .Values.gateway.nginxConfig.enableIPv6 }} + listen [::]:8080; + {{- end }} + {{- end }} + + {{- if .Values.gateway.basicAuth.enabled }} + auth_basic "Loki"; + auth_basic_user_file /etc/nginx/secrets/.htpasswd; + {{- end }} + + location = / { + return 200 'OK'; + auth_basic off; + } + + ######################################################## + # Configure backend targets + + {{- $backendHost := include "loki.backendFullname" .}} + {{- $readHost := include "loki.readFullname" .}} + {{- $writeHost := include "loki.writeFullname" .}} + + {{- if .Values.read.legacyReadTarget }} + {{- $backendHost = include "loki.readFullname" . }} + {{- end }} + + {{- $httpSchema := .Values.gateway.nginxConfig.schema }} + + {{- $writeUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $writeHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $readUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $readHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $backendUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $backendHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + + {{- if .Values.gateway.nginxConfig.customWriteUrl }} + {{- $writeUrl = .Values.gateway.nginxConfig.customWriteUrl }} + {{- end }} + {{- if .Values.gateway.nginxConfig.customReadUrl }} + {{- $readUrl = .Values.gateway.nginxConfig.customReadUrl }} + {{- end }} + {{- if .Values.gateway.nginxConfig.customBackendUrl }} + {{- $backendUrl = .Values.gateway.nginxConfig.customBackendUrl }} + {{- end }} + + {{- $singleBinaryHost := include "loki.singleBinaryFullname" . }} + {{- $singleBinaryUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $singleBinaryHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + + {{- $distributorHost := include "loki.distributorFullname" .}} + {{- $ingesterHost := include "loki.ingesterFullname" .}} + {{- $queryFrontendHost := include "loki.queryFrontendFullname" .}} + {{- $indexGatewayHost := include "loki.indexGatewayFullname" .}} + {{- $rulerHost := include "loki.rulerFullname" .}} + {{- $compactorHost := include "loki.compactorFullname" .}} + {{- $schedulerHost := include "loki.querySchedulerFullname" .}} + + + {{- $distributorUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $distributorHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) -}} + {{- $ingesterUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $ingesterHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $queryFrontendUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $queryFrontendHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $indexGatewayUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $indexGatewayHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $rulerUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $rulerHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $compactorUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $compactorHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + {{- $schedulerUrl := printf "%s://%s.%s.svc.%s:%s" $httpSchema $schedulerHost .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.http_listen_port | toString) }} + + {{- if eq (include "loki.deployment.isSingleBinary" .) "true"}} + {{- $distributorUrl = $singleBinaryUrl }} + {{- $ingesterUrl = $singleBinaryUrl }} + {{- $queryFrontendUrl = $singleBinaryUrl }} + {{- $indexGatewayUrl = $singleBinaryUrl }} + {{- $rulerUrl = $singleBinaryUrl }} + {{- $compactorUrl = $singleBinaryUrl }} + {{- $schedulerUrl = $singleBinaryUrl }} + {{- else if eq (include "loki.deployment.isScalable" .) "true"}} + {{- $distributorUrl = $writeUrl }} + {{- $ingesterUrl = $writeUrl }} + {{- $queryFrontendUrl = $readUrl }} + {{- $indexGatewayUrl = $backendUrl }} + {{- $rulerUrl = $backendUrl }} + {{- $compactorUrl = $backendUrl }} + {{- $schedulerUrl = $backendUrl }} + {{- end -}} + + {{- if .Values.loki.ui.gateway.enabled }} + location ^~ /ui { + proxy_pass {{ $distributorUrl }}$request_uri; + } + {{- end }} + + # Distributor + location = /api/prom/push { + proxy_pass {{ $distributorUrl }}$request_uri; + } + location = /loki/api/v1/push { + proxy_pass {{ $distributorUrl }}$request_uri; + } + location = /distributor/ring { + proxy_pass {{ $distributorUrl }}$request_uri; + } + location = /otlp/v1/logs { + proxy_pass {{ $distributorUrl }}$request_uri; + } + + # Ingester + location = /flush { + proxy_pass {{ $ingesterUrl }}$request_uri; + } + location ^~ /ingester/ { + proxy_pass {{ $ingesterUrl }}$request_uri; + } + location = /ingester { + internal; # to suppress 301 + } + + # Ring + location = /ring { + proxy_pass {{ $ingesterUrl }}$request_uri; + } + + # MemberListKV + location = /memberlist { + proxy_pass {{ $ingesterUrl }}$request_uri; + } + + # Ruler + location = /ruler/ring { + proxy_pass {{ $rulerUrl }}$request_uri; + } + location = /api/prom/rules { + proxy_pass {{ $rulerUrl }}$request_uri; + } + location ^~ /api/prom/rules/ { + proxy_pass {{ $rulerUrl }}$request_uri; + } + location = /loki/api/v1/rules { + proxy_pass {{ $rulerUrl }}$request_uri; + } + location ^~ /loki/api/v1/rules/ { + proxy_pass {{ $rulerUrl }}$request_uri; + } + location = /prometheus/api/v1/alerts { + proxy_pass {{ $rulerUrl }}$request_uri; + } + location = /prometheus/api/v1/rules { + proxy_pass {{ $rulerUrl }}$request_uri; + } + + # Compactor + location = /compactor/ring { + proxy_pass {{ $compactorUrl }}$request_uri; + } + location = /loki/api/v1/delete { + proxy_pass {{ $compactorUrl }}$request_uri; + } + location = /loki/api/v1/cache/generation_numbers { + proxy_pass {{ $compactorUrl }}$request_uri; + } + + # IndexGateway + location = /indexgateway/ring { + proxy_pass {{ $indexGatewayUrl }}$request_uri; + } + + # QueryScheduler + location = /scheduler/ring { + proxy_pass {{ $schedulerUrl }}$request_uri; + } + + # Config + location = /config { + proxy_pass {{ $ingesterUrl }}$request_uri; + } + + {{- if and .Values.enterprise.enabled .Values.enterprise.adminApi.enabled }} + # Admin API + location ^~ /admin/api/ { + proxy_pass {{ $backendUrl }}$request_uri; + } + location = /admin/api { + internal; # to suppress 301 + } + {{- end }} + + + # QueryFrontend, Querier + location = /api/prom/tail { + proxy_pass {{ $queryFrontendUrl }}$request_uri; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + location = /loki/api/v1/tail { + proxy_pass {{ $queryFrontendUrl }}$request_uri; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + location ^~ /api/prom/ { + proxy_pass {{ $queryFrontendUrl }}$request_uri; + } + location = /api/prom { + internal; # to suppress 301 + } + # if the X-Query-Tags header is empty, set a noop= without a value as empty values are not logged + set $query_tags $http_x_query_tags; + if ($query_tags !~* '') { + set $query_tags "noop="; + } + location ^~ /loki/api/v1/ { + # pass custom headers set by Grafana as X-Query-Tags which are logged as key/value pairs in metrics.go log messages + proxy_set_header X-Query-Tags "${query_tags},user=${http_x_grafana_user},dashboard_id=${http_x_dashboard_uid},dashboard_title=${http_x_dashboard_title},panel_id=${http_x_panel_id},panel_title=${http_x_panel_title},source_rule_uid=${http_x_rule_uid},rule_name=${http_x_rule_name},rule_folder=${http_x_rule_folder},rule_version=${http_x_rule_version},rule_source=${http_x_rule_source},rule_type=${http_x_rule_type}"; + proxy_pass {{ $queryFrontendUrl }}$request_uri; + } + location = /loki/api/v1 { + internal; # to suppress 301 + } + + {{- with .Values.gateway.nginxConfig.serverSnippet }} + {{ . | nindent 4 }} + {{- end }} + } +} +{{- end }} + +{{/* Configure enableServiceLinks in pod */}} +{{- define "loki.enableServiceLinks" -}} +{{- if semverCompare ">=1.13-0" (include "loki.kubeVersion" .) -}} +{{- if or (.Values.loki.enableServiceLinks) (ne .Values.loki.enableServiceLinks false) -}} +enableServiceLinks: true +{{- else -}} +enableServiceLinks: false +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* Determine compactor address based on target configuration */}} +{{- define "loki.compactorAddress" -}} +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- $compactorAddress := include "loki.backendFullname" . -}} +{{- if and $isSimpleScalable .Values.read.legacyReadTarget -}} +{{/* 2 target configuration */}} +{{- $compactorAddress = include "loki.readFullname" . -}} +{{- else if $isSingleBinary -}} +{{/* single binary */}} +{{- $compactorAddress = include "loki.singleBinaryFullname" . -}} +{{/* distributed */}} +{{- else if $isDistributed -}} +{{- $compactorAddress = include "loki.compactorFullname" . -}} +{{- end -}} +{{- printf "http://%s:%s" $compactorAddress (.Values.loki.server.http_listen_port | toString) }} +{{- end }} + +{{/* Determine query-scheduler address */}} +{{- define "loki.querySchedulerAddress" -}} +{{- $schedulerAddress := ""}} +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +{{- $schedulerAddress = printf "%s.%s.svc.%s:%s" (include "loki.querySchedulerFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.grpc_listen_port | toString) -}} +{{- end -}} +{{- printf "%s" $schedulerAddress }} +{{- end }} + +{{/* Determine querier address */}} +{{- define "loki.querierAddress" -}} +{{- $querierAddress := "" }} +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +{{- $querierHost := include "loki.querierFullname" .}} +{{- $querierUrl := printf "http://%s.%s.svc.%s:3100" $querierHost .Release.Namespace .Values.global.clusterDomain }} +{{- $querierAddress = $querierUrl }} +{{- end -}} +{{- printf "%s" $querierAddress }} +{{- end }} + +{{/* Determine index-gateway address */}} +{{- define "loki.indexGatewayAddress" -}} +{{- $idxGatewayAddress := ""}} +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- $isScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isDistributed -}} +{{- $idxGatewayAddress = printf "dns+%s-headless.%s.svc.%s:%s" (include "loki.indexGatewayFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.grpc_listen_port | toString) -}} +{{- end -}} +{{- if $isScalable -}} +{{- $idxGatewayAddress = printf "dns+%s-headless.%s.svc.%s:%s" (include "loki.backendFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.grpc_listen_port | toString) -}} +{{- end -}} +{{- printf "%s" $idxGatewayAddress }} +{{- end }} + +{{/* Determine bloom-planner address */}} +{{- define "loki.bloomPlannerAddress" -}} +{{- $bloomPlannerAddress := ""}} +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- $isScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isDistributed -}} +{{- $bloomPlannerAddress = printf "%s-headless.%s.svc.%s:%s" (include "loki.bloomPlannerFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.grpc_listen_port | toString) -}} +{{- end -}} +{{- if $isScalable -}} +{{- $bloomPlannerAddress = printf "%s-headless.%s.svc.%s:%s" (include "loki.backendFullname" .) .Release.Namespace .Values.global.clusterDomain (.Values.loki.server.grpc_listen_port | toString) -}} +{{- end -}} +{{- printf "%s" $bloomPlannerAddress}} +{{- end }} + +{{/* Determine bloom-gateway address */}} +{{- define "loki.bloomGatewayAddresses" -}} +{{- $bloomGatewayAddresses := ""}} +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- $isScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isDistributed -}} +{{- $bloomGatewayAddresses = printf "dnssrvnoa+_grpc._tcp.%s-headless.%s.svc.%s" (include "loki.bloomGatewayFullname" .) .Release.Namespace .Values.global.clusterDomain -}} +{{- end -}} +{{- if $isScalable -}} +{{- $bloomGatewayAddresses = printf "dnssrvnoa+_grpc._tcp.%s-headless.%s.svc.%s" (include "loki.backendFullname" .) .Release.Namespace .Values.global.clusterDomain -}} +{{- end -}} +{{- printf "%s" $bloomGatewayAddresses}} +{{- end }} + +{{- define "loki.config.checksum" -}} +checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} +{{- end -}} + +{{/* +Return the appropriate apiVersion for PodDisruptionBudget. +*/}} +{{- define "loki.pdb.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "policy/v1") (semverCompare ">=1.21-0" (include "loki.kubeVersion" .)) -}} + {{- print "policy/v1" -}} + {{- else -}} + {{- print "policy/v1beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the object store type for use with the test schema. +*/}} +{{- define "loki.testSchemaObjectStore" -}} + {{- if .Values.minio.enabled -}} + s3 + {{- else -}} + filesystem + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for HorizontalPodAutoscaler. +*/}} +{{- define "loki.hpa.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "autoscaling/v2") (semverCompare ">= 1.19-0" (include "loki.kubeVersion" .)) -}} + {{- print "autoscaling/v2" -}} + {{- else if .Capabilities.APIVersions.Has "autoscaling/v2beta2" -}} + {{- print "autoscaling/v2beta2" -}} + {{- else -}} + {{- print "autoscaling/v2beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +compute a ConfigMap or Secret checksum only based on its .data content. +This function needs to be called with a context object containing the following keys: +- ctx: the current Helm context (what '.' is at the call site) +- name: the file name of the ConfigMap or Secret +*/}} +{{- define "loki.configMapOrSecretContentHash" -}} +{{ get (include (print .ctx.Template.BasePath .name) .ctx | fromYaml) "data" | toYaml | sha256sum }} +{{- end }} + +{{/* Thanos object storage configuration helper to build +the thanos_storage_config model*/}} +{{- define "loki.thanosStorageConfig" -}} +{{- $bucketName := .bucketName }} +{{- with .ctx.Values.loki.storage.object_store }} +{{- if eq .type "s3" }} +s3: + {{- with .s3 }} + bucket_name: {{ $bucketName }} + endpoint: {{ .endpoint }} + access_key_id: {{ .access_key_id }} + secret_access_key: {{ .secret_access_key }} + region: {{ .region }} + insecure: {{ .insecure }} + http: + {{ toYaml .http | nindent 4 }} + sse: + {{ toYaml .sse | nindent 4 }} + {{- end }} +{{- else if eq .type "gcs" }} +gcs: + {{- with .gcs }} + bucket_name: {{ $bucketName }} + service_account: {{ .service_account }} + {{- end }} +{{- else if eq .type "azure" }} +azure: + {{- with .azure }} + container_name: {{ $bucketName }} + account_name: {{ .account_name }} + account_key: {{ .account_key }} + {{- end }} +{{- end }} +storage_prefix: {{ .storage_prefix }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/admin-api/_helpers.yaml b/charts/mayastor/charts/loki/templates/admin-api/_helpers.yaml new file mode 100644 index 0000000..e13ff8a --- /dev/null +++ b/charts/mayastor/charts/loki/templates/admin-api/_helpers.yaml @@ -0,0 +1,24 @@ +{{/* +adminApi fullname +*/}} +{{- define "enterprise-logs.adminApiFullname" -}} +{{ include "loki.fullname" . }}-admin-api +{{- end }} + +{{/* +adminApi common labels +*/}} +{{- define "enterprise-logs.adminApiLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: admin-api +target: admin-api +{{- end }} + +{{/* +adminApi selector labels +*/}} +{{- define "enterprise-logs.adminApiSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: admin-api +target: admin-api +{{- end }} \ No newline at end of file diff --git a/charts/mayastor/charts/loki/templates/admin-api/deployment-admin-api.yaml b/charts/mayastor/charts/loki/templates/admin-api/deployment-admin-api.yaml new file mode 100644 index 0000000..3331107 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/admin-api/deployment-admin-api.yaml @@ -0,0 +1,155 @@ +{{- if and .Values.enterprise.enabled .Values.enterprise.adminApi.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "enterprise-logs.adminApiFullname" . }} + labels: + {{- include "enterprise-logs.adminApiLabels" . | nindent 4 }} + {{- with .Values.adminApi.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + app.kubernetes.io/part-of: memberlist + annotations: + {{- with .Values.adminApi.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.adminApi.replicas }} + selector: + matchLabels: + {{- include "enterprise-logs.adminApiSelectorLabels" . | nindent 6 }} + strategy: + {{- toYaml .Values.adminApi.strategy | nindent 4 }} + template: + metadata: + labels: + {{- include "enterprise-logs.adminApiLabels" . | nindent 8 }} + {{- with merge (dict) .Values.loki.podLabels .Values.adminApi.labels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + app.kubernetes.io/part-of: memberlist + annotations: + {{- if .Values.useExternalConfig }} + checksum/config: {{ .Values.externalConfigVersion }} + {{- else }} + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- end}} + {{- with .Values.adminApi.annotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.adminApi.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ template "loki.serviceAccountName" . }} + {{- if .Values.adminApi.priorityClassName }} + priorityClassName: {{ .Values.adminApi.priorityClassName }} + {{- end }} + securityContext: + {{- toYaml .Values.adminApi.podSecurityContext | nindent 8 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.adminApi.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: admin-api + image: "{{ template "loki.image" . }}" + imagePullPolicy: {{ .Values.enterprise.image.pullPolicy }} + args: + - -target=admin-api + - -config.file=/etc/loki/config/config.yaml + {{- if .Values.minio.enabled }} + - -admin.client.backend-type=s3 + - -admin.client.s3.endpoint={{ template "loki.minio" . }} + - -admin.client.s3.bucket-name={{ .Values.loki.storage.bucketNames.admin }} + - -admin.client.s3.access-key-id={{ (index .Values.minio.users 0).accessKey }} + - -admin.client.s3.secret-access-key={{ (index .Values.minio.users 0).secretKey }} + - -admin.client.s3.insecure={{ .Values.loki.storage.s3.insecure }} + {{- end }} + {{- range $key, $value := .Values.adminApi.extraArgs }} + - "-{{ $key }}={{ $value }}" + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: license + mountPath: /etc/loki/license + - name: storage + mountPath: /data + {{- if .Values.adminApi.extraVolumeMounts }} + {{ toYaml .Values.adminApi.extraVolumeMounts | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + readinessProbe: + {{- toYaml .Values.adminApi.readinessProbe | nindent 12 }} + resources: + {{- toYaml .Values.adminApi.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.adminApi.containerSecurityContext | nindent 12 }} + env: + {{- if .Values.adminApi.env }} + {{ toYaml .Values.adminApi.env | nindent 12 }} + {{- end }} + {{- with .Values.adminApi.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.adminApi.extraContainers }} + {{ toYaml . | nindent 8 }} + {{- end }} + nodeSelector: + {{- toYaml .Values.adminApi.nodeSelector | nindent 8 }} + affinity: + {{- toYaml .Values.adminApi.affinity | nindent 8 }} + tolerations: + {{- toYaml .Values.adminApi.tolerations | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.adminApi.terminationGracePeriodSeconds }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + - name: storage + emptyDir: {} + {{- if .Values.adminApi.extraVolumes }} + {{ toYaml .Values.adminApi.extraVolumes | nindent 8 }} + {{- end }} + {{- if .Values.minio.enabled }} + - name: minio-configuration + projected: + sources: + - configMap: + name: {{ .Release.Name }}-minio + - secret: + name: {{ .Release.Name }}-minio + {{- if .Values.minio.tls.enabled }} + - name: cert-secret-volume-mc + secret: + secretName: {{ .Values.minio.tls.certSecret }} + items: + - key: {{ .Values.minio.tls.publicCrt }} + path: CAs/public.crt + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/admin-api/service-admin-api.yaml b/charts/mayastor/charts/loki/templates/admin-api/service-admin-api.yaml new file mode 100644 index 0000000..8f81723 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/admin-api/service-admin-api.yaml @@ -0,0 +1,28 @@ +{{- if and .Values.enterprise.enabled .Values.enterprise.adminApi.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "enterprise-logs.adminApiFullname" . }} + labels: + {{- include "enterprise-logs.adminApiLabels" . | nindent 4 }} + {{- with .Values.adminApi.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.adminApi.service.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3100 + protocol: TCP + targetPort: http-metrics + - name: grpc + port: 9095 + protocol: TCP + targetPort: grpc + selector: + {{- include "enterprise-logs.adminApiSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/backend/_helpers-backend.tpl b/charts/mayastor/charts/loki/templates/backend/_helpers-backend.tpl new file mode 100644 index 0000000..08f5f8f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/backend/_helpers-backend.tpl @@ -0,0 +1,32 @@ +{{/* +backend fullname +*/}} +{{- define "loki.backendFullname" -}} +{{ include "loki.name" . }}-backend +{{- end }} + +{{/* +backend common labels +*/}} +{{- define "loki.backendLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: backend +{{- end }} + +{{/* +backend selector labels +*/}} +{{- define "loki.backendSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: backend +{{- end }} + +{{/* +backend priority class name +*/}} +{{- define "loki.backendPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.backend.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/backend/clusterrole.yaml b/charts/mayastor/charts/loki/templates/backend/clusterrole.yaml new file mode 100644 index 0000000..36c8a0f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/backend/clusterrole.yaml @@ -0,0 +1,20 @@ +{{- if and (not .Values.rbac.namespaced) (not .Values.rbac.useExistingRole) }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "loki.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + name: {{ template "loki.fullname" . }}-clusterrole +{{- if .Values.sidecar.rules.enabled }} +rules: +- apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] +{{- else }} +rules: [] +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/backend/clusterrolebinding.yaml b/charts/mayastor/charts/loki/templates/backend/clusterrolebinding.yaml new file mode 100644 index 0000000..92f86a4 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/backend/clusterrolebinding.yaml @@ -0,0 +1,25 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if (not .Values.rbac.namespaced) }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "loki.fullname" . }}-clusterrolebinding + labels: + {{- include "loki.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +subjects: + - kind: ServiceAccount + name: {{ template "loki.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole +{{- if (not .Values.rbac.useExistingRole) }} + name: {{ template "loki.fullname" . }}-clusterrole +{{- else }} + name: {{ .Values.rbac.useExistingRole }} +{{- end }} + apiGroup: rbac.authorization.k8s.io +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/backend/hpa.yaml b/charts/mayastor/charts/loki/templates/backend/hpa.yaml new file mode 100644 index 0000000..ea834d6 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/backend/hpa.yaml @@ -0,0 +1,50 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- $autoscalingv2 := .Capabilities.APIVersions.Has "autoscaling/v2" -}} +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) ( .Values.backend.autoscaling.enabled ) }} +{{- if $autoscalingv2 }} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta1 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.backendFullname" . }} + labels: + {{- include "loki.backendLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.backendFullname" . }} + minReplicas: {{ .Values.backend.autoscaling.minReplicas }} + maxReplicas: {{ .Values.backend.autoscaling.maxReplicas }} + {{- with .Values.backend.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} + metrics: + {{- with .Values.backend.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.backend.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/backend/poddisruptionbudget-backend.yaml b/charts/mayastor/charts/loki/templates/backend/poddisruptionbudget-backend.yaml new file mode 100644 index 0000000..d8ce5b0 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/backend/poddisruptionbudget-backend.yaml @@ -0,0 +1,15 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (gt (int .Values.backend.replicas) 1) (not .Values.read.legacyReadTarget ) }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.backendFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.backendLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.backendSelectorLabels" . | nindent 6 }} + maxUnavailable: 1 +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/backend/query-scheduler-discovery.yaml b/charts/mayastor/charts/loki/templates/backend/query-scheduler-discovery.yaml new file mode 100644 index 0000000..4c357e5 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/backend/query-scheduler-discovery.yaml @@ -0,0 +1,34 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.querySchedulerFullname" . }}-discovery + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.backendSelectorLabels" . | nindent 4 }} + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.backend.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + selector: + {{- include "loki.backendSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/backend/service-backend-headless.yaml b/charts/mayastor/charts/loki/templates/backend/service-backend-headless.yaml new file mode 100644 index 0000000..fd90fdd --- /dev/null +++ b/charts/mayastor/charts/loki/templates/backend/service-backend-headless.yaml @@ -0,0 +1,41 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.backendFullname" . }}-headless + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.backendSelectorLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.backend.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + variant: headless + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.backend.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + appProtocol: tcp + selector: + {{- include "loki.backendSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/backend/service-backend.yaml b/charts/mayastor/charts/loki/templates/backend/service-backend.yaml new file mode 100644 index 0000000..cd1bd3b --- /dev/null +++ b/charts/mayastor/charts/loki/templates/backend/service-backend.yaml @@ -0,0 +1,37 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.backendFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.backendLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.backend.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.backend.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + selector: + {{- include "loki.backendSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/backend/statefulset-backend.yaml b/charts/mayastor/charts/loki/templates/backend/statefulset-backend.yaml new file mode 100644 index 0000000..6ed122a --- /dev/null +++ b/charts/mayastor/charts/loki/templates/backend/statefulset-backend.yaml @@ -0,0 +1,281 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.backendFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.backendLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- if or (not (empty .Values.loki.annotations)) (not (empty .Values.backend.annotations))}} + annotations: + {{- with merge (dict) .Values.loki.annotations .Values.backend.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: +{{- if not .Values.backend.autoscaling.enabled }} + {{- if eq .Values.deploymentMode "SingleBinary" }} + replicas: 0 + {{- else }} + replicas: {{ .Values.backend.replicas }} + {{- end }} +{{- end }} + podManagementPolicy: {{ .Values.backend.podManagementPolicy }} + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.backendFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.backend.persistence.enableStatefulSetAutoDeletePVC) (.Values.backend.persistence.volumeClaimsEnabled) }} + {{/* + Data on the backend nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete + {{- end }} + selector: + matchLabels: + {{- include "loki.backendSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.backend.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.backendLabels" . | nindent 8 }} + {{- with merge (dict) .Values.loki.podLabels .Values.backend.podLabels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + app.kubernetes.io/part-of: memberlist + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.backendPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.backend.terminationGracePeriodSeconds }} + {{- if .Values.backend.initContainers }} + initContainers: + {{- with .Values.backend.initContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + containers: + {{- if .Values.sidecar.rules.enabled }} + - name: loki-sc-rules + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.image.pullPolicy }} + env: + - name: METHOD + value: {{ .Values.sidecar.rules.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.rules.label }}" + {{- if .Values.sidecar.rules.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.rules.labelValue }} + {{- end }} + - name: FOLDER + value: "{{ .Values.sidecar.rules.folder }}" + - name: RESOURCE + value: {{ quote .Values.sidecar.rules.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.rules.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.rules.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + {{- if .Values.sidecar.rules.script }} + - name: SCRIPT + value: "{{ .Values.sidecar.rules.script }}" + {{- end }} + {{- if .Values.sidecar.rules.watchServerTimeout }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.rules.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.rules.watchClientTimeout }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.rules.watchClientTimeout }}" + {{- end }} + {{- if .Values.sidecar.rules.logLevel }} + - name: LOG_LEVEL + value: "{{ .Values.sidecar.rules.logLevel }}" + {{- end }} + {{- if .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml .Values.sidecar.livenessProbe | nindent 12 }} + {{- end }} + {{- if .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml .Values.sidecar.readinessProbe | nindent 12 }} + {{- end }} + {{- if .Values.sidecar.resources }} + resources: + {{- toYaml .Values.sidecar.resources | nindent 12 }} + {{- end }} + {{- if .Values.sidecar.securityContext }} + securityContext: + {{- toYaml .Values.sidecar.securityContext | nindent 12 }} + {{- end }} + volumeMounts: + - name: sc-rules-volume + mountPath: {{ .Values.sidecar.rules.folder | quote }} + {{- end}} + - name: loki + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target={{ .Values.backend.targetModule }} + - -legacy-read-mode=false + {{- with (concat .Values.global.extraArgs .Values.backend.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.loki.server.http_listen_port }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.loki.server.grpc_listen_port }} + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.backend.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnv .Values.backend.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: tmp + mountPath: /tmp + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end}} + {{- if .Values.sidecar.rules.enabled }} + - name: sc-rules-volume + mountPath: {{ .Values.sidecar.rules.folder | quote }} + {{- end}} + {{- with (concat .Values.global.extraVolumeMounts .Values.backend.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.backend.resources | nindent 12 }} + {{- with .Values.backend.extraContainers }} + {{- toYaml . | nindent 8}} + {{- end }} + {{- with .Values.backend.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.backend.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.backend.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.backend.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.backend.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: tmp + emptyDir: {} + {{- if not .Values.backend.persistence.volumeClaimsEnabled }} + - name: data + {{- toYaml .Values.backend.persistence.dataVolumeParameters | nindent 10 }} + {{- end}} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- if .Values.sidecar.rules.enabled }} + - name: sc-rules-volume + {{- if .Values.sidecar.rules.sizeLimit }} + emptyDir: + sizeLimit: {{ .Values.sidecar.rules.sizeLimit }} + {{- else }} + emptyDir: {} + {{- end -}} + {{- end -}} + {{- with (concat .Values.global.extraVolumes .Values.backend.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.backend.persistence.volumeClaimsEnabled }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + {{- with .Values.backend.persistence.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.backend.persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .Values.backend.persistence.size | quote }} + {{- with .Values.backend.persistence.selector }} + selector: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/bloom-builder/_helpers-bloom-builder.tpl b/charts/mayastor/charts/loki/templates/bloom-builder/_helpers-bloom-builder.tpl new file mode 100644 index 0000000..46359df --- /dev/null +++ b/charts/mayastor/charts/loki/templates/bloom-builder/_helpers-bloom-builder.tpl @@ -0,0 +1,32 @@ +{{/* +bloom-builder fullname +*/}} +{{- define "loki.bloomBuilderFullname" -}} +{{ include "loki.fullname" . }}-bloom-builder +{{- end }} + +{{/* +bloom-builder common labels +*/}} +{{- define "loki.bloomBuilderLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: bloom-builder +{{- end }} + +{{/* +bloom-builder selector labels +*/}} +{{- define "loki.bloomBuilderSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: bloom-builder +{{- end }} + +{{/* +bloom-builder priority class name +*/}} +{{- define "loki.bloomBuilderPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.bloomBuilder.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/bloom-builder/deployment-bloom-builder.yaml b/charts/mayastor/charts/loki/templates/bloom-builder/deployment-bloom-builder.yaml new file mode 100644 index 0000000..c7f4513 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/bloom-builder/deployment-bloom-builder.yaml @@ -0,0 +1,147 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if (and $isDistributed (gt (int .Values.bloomPlanner.replicas) 0)) -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.bloomBuilderFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomBuilderLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.bloomBuilder.autoscaling.enabled }} + replicas: {{ .Values.bloomBuilder.replicas }} +{{- end }} + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.bloomBuilderSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomBuilder.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.bloomBuilderLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.bloomBuilder.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomBuilder.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.bloomBuilderPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.bloomBuilder.terminationGracePeriodSeconds }} + containers: + - name: bloom-builder + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.bloomBuilder.command }} + command: + - {{ coalesce .Values.bloomBuilder.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=bloom-builder + {{- with (concat .Values.global.extraArgs .Values.bloomBuilder.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.bloomBuilder.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.bloomBuilder.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + - name: temp + mountPath: /tmp + - name: data + mountPath: /var/loki + {{- with (concat .Values.global.extraVolumeMounts .Values.bloomBuilder.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.bloomBuilder.resources | nindent 12 }} + {{- if .Values.bloomBuilder.extraContainers }} + {{- toYaml .Values.bloomBuilder.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.bloomBuilder.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomBuilder.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomBuilder.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + - name: temp + emptyDir: {} + - name: data + emptyDir: {} + {{- with (concat .Values.global.extraVolumes .Values.bloomBuilder.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/bloom-builder/hpa.yaml b/charts/mayastor/charts/loki/templates/bloom-builder/hpa.yaml new file mode 100644 index 0000000..2b04647 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/bloom-builder/hpa.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.bloomBuilder.autoscaling.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.bloomBuilderFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomBuilderLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "loki.bloomBuilderFullname" . }} + minReplicas: {{ .Values.bloomBuilder.autoscaling.minReplicas }} + maxReplicas: {{ .Values.bloomBuilder.autoscaling.maxReplicas }} + metrics: + {{- with .Values.bloomBuilder.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.bloomBuilder.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.bloomBuilder.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.bloomBuilder.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.bloomBuilder.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.bloomBuilder.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/bloom-builder/poddisruptionbudget-bloom-builder.yaml b/charts/mayastor/charts/loki/templates/bloom-builder/poddisruptionbudget-bloom-builder.yaml new file mode 100644 index 0000000..e66d762 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/bloom-builder/poddisruptionbudget-bloom-builder.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.bloomBuilder.replicas) 1) }} +{{- if kindIs "invalid" .Values.bloomBuilder.maxUnavailable }} +{{- fail "`.Values.bloomBuilder.maxUnavailable` must be set when `.Values.bloomBuilder.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.bloomBuilderFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomBuilderLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.bloomBuilderSelectorLabels" . | nindent 6 }} + {{- with .Values.bloomBuilder.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/bloom-builder/service-bloom-builder-headless.yaml b/charts/mayastor/charts/loki/templates/bloom-builder/service-bloom-builder-headless.yaml new file mode 100644 index 0000000..9389252 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/bloom-builder/service-bloom-builder-headless.yaml @@ -0,0 +1,46 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if (and $isDistributed (or (gt (int .Values.bloomBuilder.replicas) 0)) .Values.bloomBuilder.autoscaling.enabled) -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.bloomBuilderFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomBuilderLabels" . | nindent 4 }} + {{- with .Values.bloomBuilder.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.bloomBuilder.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + type: ClusterIP + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.bloomBuilder.appProtocol.grpc }} + appProtocol: {{ .Values.bloomBuilder.appProtocol.grpc }} + {{- end }} + - name: grpclb + port: 9096 + targetPort: grpc + protocol: TCP + {{- if .Values.bloomBuilder.appProtocol.grpc }} + appProtocol: {{ .Values.bloomBuilder.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.bloomBuilderSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/bloom-builder/service-bloom-builder.yaml b/charts/mayastor/charts/loki/templates/bloom-builder/service-bloom-builder.yaml new file mode 100644 index 0000000..b3debb0 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/bloom-builder/service-bloom-builder.yaml @@ -0,0 +1,44 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if (and $isDistributed (gt (int .Values.bloomBuilder.replicas) 0)) -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.bloomBuilderFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomBuilderLabels" . | nindent 4 }} + {{- with .Values.bloomBuilder.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.bloomBuilder.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.bloomBuilder.appProtocol.grpc }} + appProtocol: {{ .Values.bloomBuilder.appProtocol.grpc }} + {{- end }} + - name: grpclb + port: 9096 + targetPort: grpc + protocol: TCP + {{- if .Values.bloomBuilder.appProtocol.grpc }} + appProtocol: {{ .Values.bloomBuilder.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.bloomBuilderSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/bloom-gateway/_helpers-bloom-gateway.tpl b/charts/mayastor/charts/loki/templates/bloom-gateway/_helpers-bloom-gateway.tpl new file mode 100644 index 0000000..f0cef4f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/bloom-gateway/_helpers-bloom-gateway.tpl @@ -0,0 +1,58 @@ +{{/* +bloom gateway fullname +*/}} +{{- define "loki.bloomGatewayFullname" -}} +{{ include "loki.fullname" . }}-bloom-gateway +{{- end }} + +{{/* +bloom gateway common labels +*/}} +{{- define "loki.bloomGatewayLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: bloom-gateway +{{- end }} + +{{/* +bloom gateway selector labels +*/}} +{{- define "loki.bloomGatewaySelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: bloom-gateway +{{- end }} + +{{/* +bloom gateway readinessProbe +*/}} +{{- define "loki.bloomGateway.readinessProbe" -}} +{{- with .Values.bloomGateway.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +bloom gateway priority class name +*/}} +{{- define "loki.bloomGatewayPriorityClassName" }} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.bloomGateway.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} + +{{/* +Create the name of the bloom gateway service account +*/}} +{{- define "loki.bloomGatewayServiceAccountName" -}} +{{- if .Values.bloomGateway.serviceAccount.create -}} + {{ default (print (include "loki.serviceAccountName" .) "-bloom-gateway") .Values.bloomGateway.serviceAccount.name }} +{{- else -}} + {{ default (include "loki.serviceAccountName" .) .Values.bloomGateway.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/bloom-gateway/service-bloom-gateway-headless.yaml b/charts/mayastor/charts/loki/templates/bloom-gateway/service-bloom-gateway-headless.yaml new file mode 100644 index 0000000..852e4cb --- /dev/null +++ b/charts/mayastor/charts/loki/templates/bloom-gateway/service-bloom-gateway-headless.yaml @@ -0,0 +1,39 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +{{- if (gt (int .Values.bloomGateway.replicas) 0) -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.bloomGatewayFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomGatewaySelectorLabels" . | nindent 4 }} + {{- with .Values.bloomGateway.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.bloomGateway.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.bloomGateway.appProtocol.grpc }} + appProtocol: {{ .Values.bloomGateway.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.bloomGatewaySelectorLabels" . | nindent 4 }} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/bloom-gateway/statefulset-bloom-gateway.yaml b/charts/mayastor/charts/loki/templates/bloom-gateway/statefulset-bloom-gateway.yaml new file mode 100644 index 0000000..9da0f9f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/bloom-gateway/statefulset-bloom-gateway.yaml @@ -0,0 +1,180 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if (and $isDistributed (gt (int .Values.bloomGateway.replicas) 0)) -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.bloomGatewayFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomGatewayLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.bloomGateway.replicas }} + podManagementPolicy: Parallel + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.bloomGatewayFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.bloomGateway.persistence.enableStatefulSetAutoDeletePVC) }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.bloomGateway.persistence.whenDeleted }} + whenScaled: {{ .Values.bloomGateway.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.bloomGatewaySelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomGateway.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.bloomGatewayLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.bloomGateway.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomGateway.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.bloomGatewayPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.bloomGateway.terminationGracePeriodSeconds }} + {{- with .Values.bloomGateway.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: bloom-gateway + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.bloomGateway.command }} + command: + - {{ coalesce .Values.bloomGateway.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=bloom-gateway + {{- with (concat .Values.global.extraArgs .Values.bloomGateway.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.bloomGateway.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.bloomGateway.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.bloomGateway.readinessProbe" . | nindent 10 }} + volumeMounts: + - name: temp + mountPath: /tmp + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.bloomGateway.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.bloomGateway.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.bloomGateway.extraContainers }} + {{- toYaml .Values.bloomGateway.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.bloomGateway.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomGateway.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomGateway.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: temp + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- if not .Values.bloomGateway.persistence.enabled }} + - name: data + emptyDir: {} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.bloomGateway.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.bloomGateway.persistence.enabled }} + volumeClaimTemplates: + {{- range .Values.bloomGateway.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/bloom-planner/_helpers-bloom-planner.tpl b/charts/mayastor/charts/loki/templates/bloom-planner/_helpers-bloom-planner.tpl new file mode 100644 index 0000000..a4a8c6e --- /dev/null +++ b/charts/mayastor/charts/loki/templates/bloom-planner/_helpers-bloom-planner.tpl @@ -0,0 +1,58 @@ +{{/* +bloom planner fullname +*/}} +{{- define "loki.bloomPlannerFullname" -}} +{{ include "loki.fullname" . }}-bloom-planner +{{- end }} + +{{/* +bloom planner common labels +*/}} +{{- define "loki.bloomPlannerLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: bloom-planner +{{- end }} + +{{/* +bloom planner selector labels +*/}} +{{- define "loki.bloomPlannerSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: bloom-planner +{{- end }} + +{{/* +bloom planner readinessProbe +*/}} +{{- define "loki.bloomPlanner.readinessProbe" -}} +{{- with .Values.bloomPlanner.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +bloom planner priority class name +*/}} +{{- define "loki.bloomPlannerPriorityClassName" }} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.bloomPlanner.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} + +{{/* +Create the name of the bloom planner service account +*/}} +{{- define "loki.bloomPlannerServiceAccountName" -}} +{{- if .Values.bloomPlanner.serviceAccount.create -}} + {{ default (print (include "loki.serviceAccountName" .) "-bloom-planner") .Values.bloomPlanner.serviceAccount.name }} +{{- else -}} + {{ default (include "loki.serviceAccountName" .) .Values.bloomPlanner.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/bloom-planner/service-bloom-planner-headless.yaml b/charts/mayastor/charts/loki/templates/bloom-planner/service-bloom-planner-headless.yaml new file mode 100644 index 0000000..78e2633 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/bloom-planner/service-bloom-planner-headless.yaml @@ -0,0 +1,37 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if (and $isDistributed (gt (int .Values.bloomPlanner.replicas) 0)) -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.bloomPlannerFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomPlannerSelectorLabels" . | nindent 4 }} + {{- with .Values.bloomPlanner.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.bloomPlanner.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.bloomPlanner.appProtocol.grpc }} + appProtocol: {{ .Values.bloomPlanner.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.bloomPlannerSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/bloom-planner/statefulset-bloom-planner.yaml b/charts/mayastor/charts/loki/templates/bloom-planner/statefulset-bloom-planner.yaml new file mode 100644 index 0000000..349765d --- /dev/null +++ b/charts/mayastor/charts/loki/templates/bloom-planner/statefulset-bloom-planner.yaml @@ -0,0 +1,180 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if (and $isDistributed (gt (int .Values.bloomPlanner.replicas) 0)) -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.bloomPlannerFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.bloomPlannerLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.bloomPlanner.replicas }} + podManagementPolicy: Parallel + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.bloomPlannerFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.bloomPlanner.persistence.enableStatefulSetAutoDeletePVC) }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.bloomPlanner.persistence.whenDeleted }} + whenScaled: {{ .Values.bloomPlanner.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.bloomPlannerSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomPlanner.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.bloomPlannerLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.bloomPlanner.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomPlanner.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.bloomPlannerPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.bloomPlanner.terminationGracePeriodSeconds }} + {{- with .Values.bloomPlanner.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: bloom-planner + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.bloomPlanner.command }} + command: + - {{ coalesce .Values.bloomPlanner.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=bloom-planner + {{- with .Values.bloomPlanner.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with .Values.bloomPlanner.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.bloomPlanner.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.bloomPlanner.readinessProbe" . | nindent 10 }} + volumeMounts: + - name: temp + mountPath: /tmp + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with .Values.bloomPlanner.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.bloomPlanner.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.bloomPlanner.extraContainers }} + {{- toYaml .Values.bloomPlanner.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.bloomPlanner.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomPlanner.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.bloomPlanner.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: temp + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- if not .Values.bloomPlanner.persistence.enabled }} + - name: data + emptyDir: {} + {{- end }} + {{- with .Values.bloomPlanner.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.bloomPlanner.persistence.enabled }} + volumeClaimTemplates: + {{- range .Values.bloomPlanner.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/chunks-cache/poddisruptionbudget-chunks-cache.yaml b/charts/mayastor/charts/loki/templates/chunks-cache/poddisruptionbudget-chunks-cache.yaml new file mode 100644 index 0000000..da95adf --- /dev/null +++ b/charts/mayastor/charts/loki/templates/chunks-cache/poddisruptionbudget-chunks-cache.yaml @@ -0,0 +1,16 @@ +{{- if .Values.chunksCache.enabled }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.fullname" . }}-memcached-chunks-cache + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: memcached-chunks-cache +spec: + selector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: memcached-chunks-cache + maxUnavailable: 1 +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/chunks-cache/service-chunks-cache-headless.yaml b/charts/mayastor/charts/loki/templates/chunks-cache/service-chunks-cache-headless.yaml new file mode 100644 index 0000000..dc2ccd4 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/chunks-cache/service-chunks-cache-headless.yaml @@ -0,0 +1 @@ +{{- include "loki.memcached.service" (dict "ctx" $ "valuesSection" "chunksCache" "component" "chunks-cache" ) }} diff --git a/charts/mayastor/charts/loki/templates/chunks-cache/statefulset-chunks-cache.yaml b/charts/mayastor/charts/loki/templates/chunks-cache/statefulset-chunks-cache.yaml new file mode 100644 index 0000000..6a54c57 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/chunks-cache/statefulset-chunks-cache.yaml @@ -0,0 +1 @@ +{{- include "loki.memcached.statefulSet" (dict "ctx" $ "valuesSection" "chunksCache" "component" "chunks-cache" ) }} diff --git a/charts/mayastor/charts/loki/templates/ciliumnetworkpolicy.yaml b/charts/mayastor/charts/loki/templates/ciliumnetworkpolicy.yaml new file mode 100644 index 0000000..fbd2619 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ciliumnetworkpolicy.yaml @@ -0,0 +1,238 @@ +{{- if and (.Values.networkPolicy.enabled) (eq .Values.networkPolicy.flavor "cilium") }} +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-namespace-only + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: {} + egress: + - toEndpoints: + - {} + ingress: + - fromEndpoints: + - {} + +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-dns + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + egress: + - toPorts: + - ports: + - port: dns + protocol: UDP + toEndpoints: + - namespaceSelector: {} + +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-ingress + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: + matchExpressions: + - key: app.kubernetes.io/component + operator: In + values: + {{- if .Values.gateway.enabled }} + - gateway + {{- else }} + - read + - write + {{- end }} + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + ingress: + - toPorts: + - ports: + - port: http + protocol: TCP + {{- if .Values.networkPolicy.ingress.namespaceSelector }} + fromEndpoints: + - matchLabels: + {{- toYaml .Values.networkPolicy.ingress.namespaceSelector | nindent 8 }} + {{- if .Values.networkPolicy.ingress.podSelector }} + {{- toYaml .Values.networkPolicy.ingress.podSelector | nindent 8 }} + {{- end }} + {{- end }} + +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-ingress-metrics + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + ingress: + - toPorts: + - ports: + - port: http-metrics + protocol: TCP + {{- if .Values.networkPolicy.metrics.cidrs }} + {{- range $cidr := .Values.networkPolicy.metrics.cidrs }} + toCIDR: + - {{ $cidr }} + {{- end }} + {{- if .Values.networkPolicy.metrics.namespaceSelector }} + fromEndpoints: + - matchLabels: + {{- toYaml .Values.networkPolicy.metrics.namespaceSelector | nindent 8 }} + {{- if .Values.networkPolicy.metrics.podSelector }} + {{- toYaml .Values.networkPolicy.metrics.podSelector | nindent 8 }} + {{- end }} + {{- end }} + {{- end }} + +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-alertmanager + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: + matchLabels: + {{- include "loki.backendSelectorLabels" . | nindent 6 }} + egress: + - toPorts: + - ports: + - port: "{{ .Values.networkPolicy.alertmanager.port }}" + protocol: TCP + {{- if .Values.networkPolicy.alertmanager.namespaceSelector }} + toEndpoints: + - matchLabels: + {{- toYaml .Values.networkPolicy.alertmanager.namespaceSelector | nindent 8 }} + {{- if .Values.networkPolicy.alertmanager.podSelector }} + {{- toYaml .Values.networkPolicy.alertmanager.podSelector | nindent 8 }} + {{- end }} + {{- end }} + +{{- if .Values.networkPolicy.externalStorage.ports }} +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-external-storage + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + egress: + - toPorts: + - ports: + {{- range $port := .Values.networkPolicy.externalStorage.ports }} + - port: "{{ $port }}" + protocol: TCP + {{- end }} + {{- if .Values.networkPolicy.externalStorage.cidrs }} + {{- range $cidr := .Values.networkPolicy.externalStorage.cidrs }} + toCIDR: + - {{ $cidr }} + {{- end }} + {{- end }} +{{- end }} + +{{- if .Values.networkPolicy.egressWorld.enabled }} +{{- $global := . }} +{{- $componentsList := list "read" "write" "backend" }} +{{- if .Values.tableManager.enabled }} +{{- $componentsList = append $componentsList "table-manager" }} +{{- end }} +{{- range $component := $componentsList }} +{{- with $global }} +--- +apiVersion: "cilium.io/v2" +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-{{ $component }}-world-egress + namespace: {{ .Release.Namespace }} +spec: + endpointSelector: + matchLabels: + {{- if eq $component "read" }} + {{- include "loki.readSelectorLabels" . | nindent 6 }} + {{- else if eq $component "write" }} + {{- include "loki.writeSelectorLabels" . | nindent 6 }} + {{- else if eq $component "table-manager" }} + {{- include "loki.tableManagerSelectorLabels" . | nindent 6 }} + {{- else }} + {{- include "loki.backendSelectorLabels" . | nindent 6 }} + {{- end }} + egress: + - toEntities: + - world +{{- end }} +{{- end }} +{{- end }} + +{{- if .Values.networkPolicy.egressKubeApiserver.enabled }} +--- +apiVersion: "cilium.io/v2" +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-backend-kubeapiserver-egress + namespace: {{ .Release.Namespace }} +spec: + endpointSelector: + matchLabels: + {{- include "loki.backendSelectorLabels" . | nindent 6 }} + egress: + - toEntities: + - kube-apiserver +{{- end }} + +{{- end }} + +{{- if and .Values.networkPolicy.discovery.port (eq .Values.networkPolicy.flavor "cilium") }} +--- +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-discovery + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + endpointSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + egress: + - toPorts: + - ports: + - port: "{{ .Values.networkPolicy.discovery.port }}" + protocol: TCP + {{- if .Values.networkPolicy.discovery.namespaceSelector }} + toEndpoints: + - matchLabels: + {{- toYaml .Values.networkPolicy.discovery.namespaceSelector | nindent 8 }} + {{- if .Values.networkPolicy.discovery.podSelector }} + {{- toYaml .Values.networkPolicy.discovery.podSelector | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/compactor/_helpers-compactor.tpl b/charts/mayastor/charts/loki/templates/compactor/_helpers-compactor.tpl new file mode 100644 index 0000000..75c21db --- /dev/null +++ b/charts/mayastor/charts/loki/templates/compactor/_helpers-compactor.tpl @@ -0,0 +1,81 @@ +{{/* +compactor fullname +*/}} +{{- define "loki.compactorFullname" -}} +{{ include "loki.fullname" . }}-compactor +{{- end }} + +{{/* +compactor common labels +*/}} +{{- define "loki.compactorLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: compactor +{{- end }} + +{{/* +compactor selector labels +*/}} +{{- define "loki.compactorSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: compactor +{{- end }} + +{{/* +compactor image +*/}} +{{- define "loki.compactorImage" -}} +{{- $dict := dict "loki" .Values.loki.image "service" .Values.compactor.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}} +{{- include "loki.lokiImage" $dict -}} +{{- end }} + +{{/* +compactor readinessProbe +*/}} +{{- define "loki.compactor.readinessProbe" -}} +{{- with .Values.compactor.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +compactor livenessProbe +*/}} +{{- define "loki.compactor.livenessProbe" -}} +{{- with .Values.compactor.livenessProbe }} +livenessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.livenessProbe }} +livenessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +compactor priority class name +*/}} +{{- define "loki.compactorPriorityClassName" }} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.compactor.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} + +{{/* +Create the name of the compactor service account +*/}} +{{- define "loki.compactorServiceAccountName" -}} +{{- if .Values.compactor.serviceAccount.create -}} + {{ default (print (include "loki.serviceAccountName" .) "-compactor") .Values.compactor.serviceAccount.name }} +{{- else -}} + {{ default (include "loki.serviceAccountName" .) .Values.compactor.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/compactor/service-compactor.yaml b/charts/mayastor/charts/loki/templates/compactor/service-compactor.yaml new file mode 100644 index 0000000..f118b6c --- /dev/null +++ b/charts/mayastor/charts/loki/templates/compactor/service-compactor.yaml @@ -0,0 +1,38 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.compactorFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} + {{- with .Values.compactor.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + app.kubernetes.io/component: compactor + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.compactor.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.compactor.appProtocol.grpc }} + appProtocol: {{ .Values.compactor.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: compactor +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/compactor/statefulset-compactor.yaml b/charts/mayastor/charts/loki/templates/compactor/statefulset-compactor.yaml new file mode 100644 index 0000000..b0a4969 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/compactor/statefulset-compactor.yaml @@ -0,0 +1,192 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.compactorFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.compactorLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.compactor.replicas }} + podManagementPolicy: Parallel + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.compactorFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.compactor.persistence.enableStatefulSetAutoDeletePVC) }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.compactor.persistence.whenDeleted }} + whenScaled: {{ .Values.compactor.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.compactorSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.compactor.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.compactorLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.compactor.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.compactor.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.compactor.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.compactorPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.compactor.terminationGracePeriodSeconds }} + {{- with .Values.compactor.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: compactor + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.compactor.command }} + command: + - {{ coalesce .Values.compactor.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=compactor + {{- with (concat .Values.global.extraArgs .Values.compactor.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.compactor.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.compactor.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.compactor.readinessProbe" . | nindent 10 }} + {{- include "loki.compactor.livenessProbe" . | nindent 10 }} + volumeMounts: + - name: temp + mountPath: /tmp + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.compactor.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.compactor.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.compactor.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.compactor.extraContainers }} + {{- toYaml .Values.compactor.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.compactor.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.compactor.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.compactor.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: temp + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- if not .Values.compactor.persistence.enabled }} + - name: data + emptyDir: {} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.compactor.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.compactor.persistence.enabled }} + volumeClaimTemplates: + {{- range .Values.compactor.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/config.yaml b/charts/mayastor/charts/loki/templates/config.yaml new file mode 100644 index 0000000..fe47590 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/config.yaml @@ -0,0 +1,21 @@ +{{- if .Values.loki.generatedConfigObjectName -}} +apiVersion: v1 +{{- if eq .Values.loki.configStorageType "Secret" }} +kind: Secret +{{- else }} +kind: ConfigMap +{{- end }} +metadata: + name: {{ tpl .Values.loki.generatedConfigObjectName . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +{{- if eq .Values.loki.configStorageType "Secret" }} +data: + config.yaml: {{ include "loki.calculatedConfig" . | b64enc }} +{{- else }} +data: + config.yaml: | + {{ include "loki.calculatedConfig" . | nindent 4 }} +{{- end -}} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/distributor/_helpers-distributor.tpl b/charts/mayastor/charts/loki/templates/distributor/_helpers-distributor.tpl new file mode 100644 index 0000000..c23179e --- /dev/null +++ b/charts/mayastor/charts/loki/templates/distributor/_helpers-distributor.tpl @@ -0,0 +1,32 @@ +{{/* +distributor fullname +*/}} +{{- define "loki.distributorFullname" -}} +{{ include "loki.fullname" . }}-distributor +{{- end }} + +{{/* +distributor common labels +*/}} +{{- define "loki.distributorLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: distributor +{{- end }} + +{{/* +distributor selector labels +*/}} +{{- define "loki.distributorSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: distributor +{{- end }} + +{{/* +distributor priority class name +*/}} +{{- define "loki.distributorPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.distributor.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/distributor/deployment-distributor.yaml b/charts/mayastor/charts/loki/templates/distributor/deployment-distributor.yaml new file mode 100644 index 0000000..8b6d6c9 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/distributor/deployment-distributor.yaml @@ -0,0 +1,155 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.distributorFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.distributorLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.distributor.autoscaling.enabled }} + replicas: {{ .Values.distributor.replicas }} +{{- end }} + strategy: + rollingUpdate: + maxSurge: {{ .Values.distributor.maxSurge }} + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.distributorSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.distributor.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.distributorLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.distributor.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.distributor.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.distributor.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.distributorPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.distributor.terminationGracePeriodSeconds }} + containers: + - name: distributor + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.distributor.command }} + command: + - {{ coalesce .Values.distributor.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=distributor + {{- if .Values.ingester.zoneAwareReplication.enabled }} + {{- if and (.Values.ingester.zoneAwareReplication.migration.enabled) (not .Values.ingester.zoneAwareReplication.migration.writePath) }} + - -distributor.zone-awareness-enabled=false + {{- else }} + - -distributor.zone-awareness-enabled=true + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraArgs .Values.distributor.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.distributor.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.distributor.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + livenessProbe: + {{- toYaml .Values.loki.livenessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.distributor.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.distributor.resources | nindent 12 }} + {{- if .Values.distributor.extraContainers }} + {{- toYaml .Values.distributor.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.distributor.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.distributor.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.distributor.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.distributor.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/distributor/hpa.yaml b/charts/mayastor/charts/loki/templates/distributor/hpa.yaml new file mode 100644 index 0000000..838a310 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/distributor/hpa.yaml @@ -0,0 +1,54 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.distributor.autoscaling.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.distributorFullname" . }} + labels: + {{- include "loki.distributorLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "loki.distributorFullname" . }} + minReplicas: {{ .Values.distributor.autoscaling.minReplicas }} + maxReplicas: {{ .Values.distributor.autoscaling.maxReplicas }} + metrics: + {{- with .Values.distributor.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.distributor.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.distributor.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.distributor.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.distributor.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.distributor.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/distributor/poddisruptionbudget-distributor.yaml b/charts/mayastor/charts/loki/templates/distributor/poddisruptionbudget-distributor.yaml new file mode 100644 index 0000000..806a447 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/distributor/poddisruptionbudget-distributor.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.distributor.replicas) 1) }} +{{- if kindIs "invalid" .Values.distributor.maxUnavailable }} +{{- fail "`.Values.distributor.maxUnavailable` must be set when `.Values.distributor.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.distributorFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.distributorLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.distributorSelectorLabels" . | nindent 6 }} + {{- with .Values.distributor.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/distributor/service-distributor-headless.yaml b/charts/mayastor/charts/loki/templates/distributor/service-distributor-headless.yaml new file mode 100644 index 0000000..650b629 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/distributor/service-distributor-headless.yaml @@ -0,0 +1,39 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.distributorFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.distributorSelectorLabels" . | nindent 4 }} + {{- with .Values.distributor.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + variant: headless + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.distributor.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.distributor.appProtocol.grpc }} + appProtocol: {{ .Values.distributor.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.distributorSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/distributor/service-distributor.yaml b/charts/mayastor/charts/loki/templates/distributor/service-distributor.yaml new file mode 100644 index 0000000..6a89956 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/distributor/service-distributor.yaml @@ -0,0 +1,36 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.distributorFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.distributorLabels" . | nindent 4 }} + {{- with .Values.distributor.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.distributor.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.distributor.appProtocol.grpc }} + appProtocol: {{ .Values.distributor.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.distributorSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/extra-manifests.yaml b/charts/mayastor/charts/loki/templates/extra-manifests.yaml new file mode 100644 index 0000000..7b69423 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/extra-manifests.yaml @@ -0,0 +1,8 @@ +{{- range .Values.extraObjects }} +--- +{{- if kindIs "map" . }} +{{ tpl (toYaml .) $ }} +{{- else }} +{{ tpl . $ }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/gateway/_helpers-gateway.tpl b/charts/mayastor/charts/loki/templates/gateway/_helpers-gateway.tpl new file mode 100644 index 0000000..39890b1 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/gateway/_helpers-gateway.tpl @@ -0,0 +1,47 @@ +{{/* +gateway fullname +*/}} +{{- define "loki.gatewayFullname" -}} +{{ include "loki.fullname" . }}-gateway +{{- end }} + +{{/* +gateway common labels +*/}} +{{- define "loki.gatewayLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: gateway +{{- end }} + +{{/* +gateway selector labels +*/}} +{{- define "loki.gatewaySelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: gateway +{{- end }} + +{{/* +gateway auth secret name +*/}} +{{- define "loki.gatewayAuthSecret" -}} +{{ .Values.gateway.basicAuth.existingSecret | default (include "loki.gatewayFullname" . ) }} +{{- end }} + +{{/* +gateway Docker image +*/}} +{{- define "loki.gatewayImage" -}} +{{- $dict := dict "service" .Values.gateway.image "global" .Values.global.image -}} +{{- include "loki.baseImage" $dict -}} +{{- end }} + +{{/* +gateway priority class name +*/}} +{{- define "loki.gatewayPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.gateway.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/gateway/configmap-gateway.yaml b/charts/mayastor/charts/loki/templates/gateway/configmap-gateway.yaml new file mode 100644 index 0000000..1c981a7 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/gateway/configmap-gateway.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.gateway.enabled (not (and .Values.enterprise.enabled .Values.enterprise.gelGateway)) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "loki.gatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} +data: + nginx.conf: | + {{- tpl .Values.gateway.nginxConfig.file . | indent 2 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/gateway/deployment-gateway-enterprise.yaml b/charts/mayastor/charts/loki/templates/gateway/deployment-gateway-enterprise.yaml new file mode 100644 index 0000000..6e9bb15 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/gateway/deployment-gateway-enterprise.yaml @@ -0,0 +1,152 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and .Values.gateway.enabled .Values.enterprise.enabled .Values.enterprise.gelGateway }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "loki.gatewayFullname" . }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} + {{- with .Values.enterpriseGateway.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterpriseGateway.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.enterpriseGateway.replicas }} + selector: + matchLabels: + {{- include "loki.gatewaySelectorLabels" . | nindent 6 }} + strategy: + {{- toYaml .Values.enterpriseGateway.strategy | nindent 4 }} + template: + metadata: + labels: + {{- include "loki.gatewaySelectorLabels" . | nindent 8 }} + {{- with .Values.enterpriseGateway.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{- if .Values.useExternalConfig }} + checksum/config: {{ .Values.externalConfigVersion }} + {{- else }} + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- end}} + {{- with .Values.enterpriseGateway.annotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.enterpriseGateway.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ template "loki.serviceAccountName" . }} + {{- if .Values.enterpriseGateway.priorityClassName }} + priorityClassName: {{ .Values.enterpriseGateway.priorityClassName }} + {{- end }} + securityContext: + {{- toYaml .Values.enterpriseGateway.podSecurityContext | nindent 8 }} + initContainers: + {{- toYaml .Values.enterpriseGateway.initContainers | nindent 8 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.enterpriseGateway.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: gateway + image: "{{ template "loki.image" . }}" + imagePullPolicy: {{ .Values.enterprise.image.pullPolicy }} + args: + - -target=gateway + - -config.file=/etc/loki/config/config.yaml + {{- if .Values.minio.enabled }} + - -admin.client.backend-type=s3 + - -admin.client.s3.endpoint={{ template "loki.minio" . }} + - -admin.client.s3.bucket-name={{ .Values.loki.storage.bucketNames.admin }} + - -admin.client.s3.access-key-id={{ (index .Values.minio.users 0).accessKey }} + - -admin.client.s3.secret-access-key={{ (index .Values.minio.users 0).secretKey }} + - -admin.client.s3.insecure={{ .Values.loki.storage.s3.insecure }} + {{- end }} + {{- if and $isDistributed .Values.enterpriseGateway.useDefaultProxyURLs }} + - -gateway.proxy.default.url=http://{{ template "loki.fullname" . }}-admin-api.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.admin-api.url=http://{{ template "loki.fullname" . }}-admin-api.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.distributor.url=dns:///{{ template "loki.fullname" . }}-distributor-headless.{{ .Release.Namespace }}.svc:9095 + - -gateway.proxy.ingester.url=http://{{ template "loki.fullname" . }}-ingester.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.query-frontend.url=http://{{ template "loki.fullname" . }}-query-frontend.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.ruler.url=http://{{ template "loki.fullname" . }}-ruler.{{ .Release.Namespace }}.svc:3100 + {{- end }} + {{- if and $isSimpleScalable .Values.enterpriseGateway.useDefaultProxyURLs }} + - -gateway.proxy.default.url=http://{{ template "enterprise-logs.adminApiFullname" . }}.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.admin-api.url=http://{{ template "enterprise-logs.adminApiFullname" . }}.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.compactor.url=http://{{ template "loki.backendFullname" . }}-headless.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.distributor.url=dns:///{{ template "loki.writeFullname" . }}-headless.{{ .Release.Namespace }}.svc:9095 + - -gateway.proxy.ingester.url=http://{{ template "loki.writeFullname" . }}.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.query-frontend.url=http://{{ template "loki.readFullname" . }}.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.ruler.url=http://{{ template "loki.backendFullname" . }}-headless.{{ .Release.Namespace }}.svc:3100 + - -gateway.proxy.query-scheduler.url=http://{{ template "loki.backendFullname" . }}-headless.{{ .Release.Namespace }}.svc:3100 + {{- end }} + {{- range $key, $value := .Values.enterpriseGateway.extraArgs }} + - "-{{ $key }}={{ $value }}" + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: license + mountPath: /etc/loki/license + - name: storage + mountPath: /data + {{- if .Values.enterpriseGateway.extraVolumeMounts }} + {{ toYaml .Values.enterpriseGateway.extraVolumeMounts | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + readinessProbe: + {{- toYaml .Values.enterpriseGateway.readinessProbe | nindent 12 }} + resources: + {{- toYaml .Values.enterpriseGateway.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.enterpriseGateway.containerSecurityContext | nindent 12 }} + env: + {{- if .Values.enterpriseGateway.env }} + {{ toYaml .Values.enterpriseGateway.env | nindent 12 }} + {{- end }} + {{- with .Values.enterpriseGateway.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.enterpriseGateway.extraContainers }} + {{ toYaml . | nindent 8 }} + {{- end }} + nodeSelector: + {{- toYaml .Values.enterpriseGateway.nodeSelector | nindent 8 }} + affinity: + {{- toYaml .Values.enterpriseGateway.affinity | nindent 8 }} + tolerations: + {{- toYaml .Values.enterpriseGateway.tolerations | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.enterpriseGateway.terminationGracePeriodSeconds }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + - name: storage + emptyDir: {} + {{- if .Values.enterpriseGateway.extraVolumes }} + {{ toYaml .Values.enterpriseGateway.extraVolumes | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/gateway/deployment-gateway-nginx.yaml b/charts/mayastor/charts/loki/templates/gateway/deployment-gateway-nginx.yaml new file mode 100644 index 0000000..94562ad --- /dev/null +++ b/charts/mayastor/charts/loki/templates/gateway/deployment-gateway-nginx.yaml @@ -0,0 +1,138 @@ +{{- if and .Values.gateway.enabled (not (and .Values.enterprise.enabled .Values.enterprise.gelGateway)) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.gatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} + {{- if or (not (empty .Values.loki.annotations)) (not (empty .Values.backend.annotations))}} + annotations: + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.gateway.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: +{{- if not .Values.gateway.autoscaling.enabled }} + replicas: {{ .Values.gateway.replicas }} +{{- end }} +{{- with .Values.gateway.deploymentStrategy }} + strategy: +{{ toYaml . | trim | indent 4 }} +{{- end }} + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.gatewaySelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/gateway/configmap-gateway.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.gateway.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- with .Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.gateway.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.gatewaySelectorLabels" . | nindent 8 }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{ include "loki.enableServiceLinks" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end -}} + {{- include "loki.gatewayPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.gateway.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.gateway.terminationGracePeriodSeconds }} + containers: + - name: nginx + image: {{ include "loki.gatewayImage" . }} + imagePullPolicy: {{ .Values.gateway.image.pullPolicy }} + ports: + - name: http-metrics + containerPort: {{ .Values.gateway.containerPort }} + protocol: TCP + {{- with .Values.gateway.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.gateway.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + readinessProbe: + {{- toYaml .Values.gateway.readinessProbe | nindent 12 }} + securityContext: + {{- toYaml .Values.gateway.containerSecurityContext | nindent 12 }} + {{- with .Values.gateway.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/nginx + {{- if .Values.gateway.basicAuth.enabled }} + - name: auth + mountPath: /etc/nginx/secrets + {{- end }} + - name: tmp + mountPath: /tmp + - name: docker-entrypoint-d-override + mountPath: /docker-entrypoint.d + {{- if .Values.gateway.extraVolumeMounts }} + {{- toYaml .Values.gateway.extraVolumeMounts | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.gateway.resources | nindent 12 }} + {{- if .Values.gateway.extraContainers }} + {{- toYaml .Values.gateway.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.gateway.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.gateway.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.gateway.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.gateway.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.gateway.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "loki.gatewayFullname" . }} + {{- if .Values.gateway.basicAuth.enabled }} + - name: auth + secret: + secretName: {{ include "loki.gatewayAuthSecret" . }} + {{- end }} + - name: tmp + emptyDir: {} + - name: docker-entrypoint-d-override + emptyDir: {} + {{- if .Values.gateway.extraVolumes }} + {{- toYaml .Values.gateway.extraVolumes | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/gateway/hpa.yaml b/charts/mayastor/charts/loki/templates/gateway/hpa.yaml new file mode 100644 index 0000000..3541ec6 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/gateway/hpa.yaml @@ -0,0 +1,50 @@ +{{- $autoscalingv2 := .Capabilities.APIVersions.Has "autoscaling/v2" -}} +{{- if .Values.gateway.autoscaling.enabled }} +{{- if $autoscalingv2 }} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta1 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.gatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "loki.gatewayFullname" . }} + minReplicas: {{ .Values.gateway.autoscaling.minReplicas }} + maxReplicas: {{ .Values.gateway.autoscaling.maxReplicas }} + {{- with .Values.gateway.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} + metrics: + {{- with .Values.gateway.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.gateway.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/gateway/ingress-gateway.yaml b/charts/mayastor/charts/loki/templates/gateway/ingress-gateway.yaml new file mode 100644 index 0000000..6f18e33 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/gateway/ingress-gateway.yaml @@ -0,0 +1,59 @@ +{{- if and .Values.gateway.enabled -}} +{{- if .Values.gateway.ingress.enabled -}} +{{- $ingressApiIsStable := eq (include "loki.ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "loki.ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "loki.ingress.supportsPathType" .) "true" -}} +apiVersion: {{ include "loki.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ include "loki.gatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} + {{- range $labelKey, $labelValue := .Values.gateway.ingress.labels }} + {{ $labelKey }}: {{ $labelValue | toYaml }} + {{- end }} + {{- with .Values.gateway.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.gateway.ingress.ingressClassName }} + ingressClassName: {{ .Values.gateway.ingress.ingressClassName }} + {{- end -}} + {{- if .Values.gateway.ingress.tls }} + tls: + {{- range .Values.gateway.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ tpl . $ | quote }} + {{- end }} + {{- with .secretName }} + secretName: {{ . }} + {{- end }} + {{- end }} + {{- end }} + rules: + {{- range .Values.gateway.ingress.hosts }} + - host: {{ tpl .host $ | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if $ingressSupportsPathType }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ include "loki.gatewayFullname" $ }} + port: + number: {{ $.Values.gateway.service.port }} + {{- else }} + serviceName: {{ include "loki.gatewayFullname" $ }} + servicePort: {{ $.Values.gateway.service.port }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/gateway/poddisruptionbudget-gateway.yaml b/charts/mayastor/charts/loki/templates/gateway/poddisruptionbudget-gateway.yaml new file mode 100644 index 0000000..0057c56 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/gateway/poddisruptionbudget-gateway.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.gateway.enabled }} +{{- if or + (and (not .Values.gateway.autoscaling.enabled) (gt (int .Values.gateway.replicas) 1)) + (and .Values.gateway.autoscaling.enabled (gt (int .Values.gateway.autoscaling.minReplicas) 1)) +}} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.gatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.gatewaySelectorLabels" . | nindent 6 }} + maxUnavailable: 1 +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/gateway/secret-gateway.yaml b/charts/mayastor/charts/loki/templates/gateway/secret-gateway.yaml new file mode 100644 index 0000000..c3c5e9a --- /dev/null +++ b/charts/mayastor/charts/loki/templates/gateway/secret-gateway.yaml @@ -0,0 +1,14 @@ +{{- with .Values.gateway }} +{{- if and .enabled .basicAuth.enabled (not .basicAuth.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "loki.gatewayFullname" $ }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" $ | nindent 4 }} +stringData: + .htpasswd: | + {{- tpl .basicAuth.htpasswd $ | nindent 4 }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/gateway/service-gateway.yaml b/charts/mayastor/charts/loki/templates/gateway/service-gateway.yaml new file mode 100644 index 0000000..af44d0e --- /dev/null +++ b/charts/mayastor/charts/loki/templates/gateway/service-gateway.yaml @@ -0,0 +1,43 @@ +{{- if .Values.gateway.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.gatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.gatewayLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.gateway.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if not (and .Values.enterprise.enabled .Values.enterprise.gelGateway) }} + prometheus.io/service-monitor: "false" + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.gateway.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: {{ .Values.gateway.service.type }} + {{- with .Values.gateway.service.clusterIP }} + clusterIP: {{ . }} + {{- end }} + {{- if and (eq "LoadBalancer" .Values.gateway.service.type) .Values.gateway.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.gateway.service.loadBalancerIP }} + {{- end }} + ports: + - name: http-metrics + port: {{ .Values.gateway.service.port }} + targetPort: http-metrics + {{- if and (eq "NodePort" .Values.gateway.service.type) .Values.gateway.service.nodePort }} + nodePort: {{ .Values.gateway.service.nodePort }} + {{- end }} + protocol: TCP + selector: + {{- include "loki.gatewaySelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/index-gateway/_helpers-index-gateway.tpl b/charts/mayastor/charts/loki/templates/index-gateway/_helpers-index-gateway.tpl new file mode 100644 index 0000000..f42dff3 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/index-gateway/_helpers-index-gateway.tpl @@ -0,0 +1,40 @@ +{{/* +index-gateway fullname +*/}} +{{- define "loki.indexGatewayFullname" -}} +{{ include "loki.fullname" . }}-index-gateway +{{- end }} + +{{/* +index-gateway common labels +*/}} +{{- define "loki.indexGatewayLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: index-gateway +{{- end }} + +{{/* +index-gateway selector labels +*/}} +{{- define "loki.indexGatewaySelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: index-gateway +{{- end }} + +{{/* +index-gateway image +*/}} +{{- define "loki.indexGatewayImage" -}} +{{- $dict := dict "loki" .Values.loki.image "service" .Values.indexGateway.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}} +{{- include "loki.lokiImage" $dict -}} +{{- end }} + +{{/* +index-gateway priority class name +*/}} +{{- define "loki.indexGatewayPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.indexGateway.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/index-gateway/poddisruptionbudget-index-gateway.yaml b/charts/mayastor/charts/loki/templates/index-gateway/poddisruptionbudget-index-gateway.yaml new file mode 100644 index 0000000..cc230c2 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/index-gateway/poddisruptionbudget-index-gateway.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.indexGateway.replicas) 1) }} +{{- if kindIs "invalid" .Values.indexGateway.maxUnavailable }} +{{- fail "`.Values.indexGateway.maxUnavailable` must be set when `.Values.indexGateway.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.indexGatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.indexGatewayLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.indexGatewaySelectorLabels" . | nindent 6 }} + {{- with .Values.indexGateway.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/index-gateway/service-index-gateway-headless.yaml b/charts/mayastor/charts/loki/templates/index-gateway/service-index-gateway-headless.yaml new file mode 100644 index 0000000..731a984 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/index-gateway/service-index-gateway-headless.yaml @@ -0,0 +1,35 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.indexGatewayFullname" . }}-headless + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.indexGatewaySelectorLabels" . | nindent 4 }} + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.indexGateway.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- with .Values.indexGateway.appProtocol.grpc }} + appProtocol: {{ . }} + {{- end }} + selector: + {{- include "loki.indexGatewaySelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/index-gateway/service-index-gateway.yaml b/charts/mayastor/charts/loki/templates/index-gateway/service-index-gateway.yaml new file mode 100644 index 0000000..b1a3523 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/index-gateway/service-index-gateway.yaml @@ -0,0 +1,36 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.indexGatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.indexGatewayLabels" . | nindent 4 }} + {{- with .Values.indexGateway.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.indexGateway.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- with .Values.indexGateway.appProtocol.grpc }} + appProtocol: {{ . }} + {{- end }} + selector: + {{- include "loki.indexGatewaySelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/index-gateway/statefulset-index-gateway.yaml b/charts/mayastor/charts/loki/templates/index-gateway/statefulset-index-gateway.yaml new file mode 100644 index 0000000..0a725e9 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/index-gateway/statefulset-index-gateway.yaml @@ -0,0 +1,191 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.indexGatewayFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.indexGatewayLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.indexGateway.replicas }} +{{- with .Values.indexGateway.updateStrategy }} + updateStrategy: + {{- tpl (. | toYaml) $ | nindent 4 }} +{{- end }} + serviceName: {{ include "loki.indexGatewayFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.indexGateway.persistence.enableStatefulSetAutoDeletePVC) }} + {{/* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.indexGateway.persistence.whenDeleted }} + whenScaled: {{ .Values.indexGateway.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.indexGatewaySelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.indexGateway.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.indexGatewayLabels" . | nindent 8 }} + {{- with merge (dict) .Values.loki.podLabels .Values.indexGateway.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.indexGateway.joinMemberlist }} + app.kubernetes.io/part-of: memberlist + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.indexGateway.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.indexGatewayPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.indexGateway.terminationGracePeriodSeconds }} + {{- with .Values.indexGateway.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: index-gateway + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=index-gateway + {{- with (concat .Values.global.extraArgs .Values.indexGateway.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + {{- if .Values.indexGateway.joinMemberlist }} + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- end }} + {{- with (concat .Values.global.extraEnv .Values.indexGateway.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.indexGateway.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + livenessProbe: + {{- toYaml .Values.loki.livenessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.indexGateway.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.indexGateway.resources | nindent 12 }} + {{- if .Values.indexGateway.extraContainers }} + {{- toYaml .Values.indexGateway.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.indexGateway.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.indexGateway.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.indexGateway.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.indexGateway.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.indexGateway.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.indexGateway.persistence.enabled }} + - name: data + emptyDir: {} + {{- else if .Values.indexGateway.persistence.inMemory }} + - name: data + {{- if .Values.indexGateway.persistence.inMemory }} + emptyDir: + medium: Memory + {{- end }} + {{- if .Values.indexGateway.persistence.size }} + sizeLimit: {{ .Values.indexGateway.persistence.size }} + {{- end }} + {{- else }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + {{- with .Values.indexGateway.persistence.annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.indexGateway.persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .Values.indexGateway.persistence.size | quote }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ingester/_helpers-ingester.tpl b/charts/mayastor/charts/loki/templates/ingester/_helpers-ingester.tpl new file mode 100644 index 0000000..70728a0 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/_helpers-ingester.tpl @@ -0,0 +1,92 @@ +{{/* +ingester fullname +*/}} +{{- define "loki.ingesterFullname" -}} +{{ include "loki.fullname" . }}-ingester +{{- end }} + +{{/* +ingester common labels +*/}} +{{- define "loki.ingesterLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: ingester +{{- end }} + +{{/* +ingester selector labels +*/}} +{{- define "loki.ingesterSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: ingester +{{- end }} + +{{/* +ingester priority class name +*/}} +{{- define "loki.ingesterPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.ingester.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} + +{{- define "loki.ingester.readinessProbe" -}} +{{- with .Values.ingester.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{- define "loki.ingester.livenessProbe" -}} +{{- with .Values.ingester.livenessProbe }} +livenessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.livenessProbe }} +livenessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +expects global context +*/}} +{{- define "loki.ingester.replicaCount" -}} +{{- ceil (divf .Values.ingester.replicas 3) -}} +{{- end -}} + +{{/* +expects a dict +{ + "replicas": replicas in a zone, + "ctx": global context +} +*/}} +{{- define "loki.ingester.maxUnavailable" -}} +{{- ceil (mulf .replicas (divf (int .ctx.Values.ingester.zoneAwareReplication.maxUnavailablePct) 100)) -}} +{{- end -}} + +{{/* +Return rollout-group prefix if it is set +*/}} +{{- define "loki.prefixRolloutGroup" -}} +{{- if .Values.ingester.rolloutGroupPrefix -}} +{{- .Values.ingester.rolloutGroupPrefix -}}- +{{- end -}} +{{- end -}} + +{{/* +Return ingester name prefix if required +*/}} +{{- define "loki.prefixIngesterName" -}} +{{- if .Values.ingester.addIngesterNamePrefix -}} +loki- +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/ingester/hpa-zone-a.yaml b/charts/mayastor/charts/loki/templates/ingester/hpa-zone-a.yaml new file mode 100644 index 0000000..5ede187 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/hpa-zone-a.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.autoscaling.enabled .Values.ingester.zoneAwareReplication.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-a + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.ingesterFullname" . }}-zone-a + minReplicas: {{ .Values.ingester.autoscaling.minReplicas }} + maxReplicas: {{ .Values.ingester.autoscaling.maxReplicas }} + metrics: + {{- with .Values.ingester.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingester.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.ingester.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.ingester.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ingester/hpa-zone-b.yaml b/charts/mayastor/charts/loki/templates/ingester/hpa-zone-b.yaml new file mode 100644 index 0000000..b001a6a --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/hpa-zone-b.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.autoscaling.enabled .Values.ingester.zoneAwareReplication.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-b + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.ingesterFullname" . }}-zone-b + minReplicas: {{ .Values.ingester.autoscaling.minReplicas }} + maxReplicas: {{ .Values.ingester.autoscaling.maxReplicas }} + metrics: + {{- with .Values.ingester.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingester.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.ingester.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.ingester.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ingester/hpa-zone-c.yaml b/charts/mayastor/charts/loki/templates/ingester/hpa-zone-c.yaml new file mode 100644 index 0000000..82f229c --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/hpa-zone-c.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.autoscaling.enabled .Values.ingester.zoneAwareReplication.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-c + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.ingesterFullname" . }}-zone-c + minReplicas: {{ .Values.ingester.autoscaling.minReplicas }} + maxReplicas: {{ .Values.ingester.autoscaling.maxReplicas }} + metrics: + {{- with .Values.ingester.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingester.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.ingester.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.ingester.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ingester/hpa.yaml b/charts/mayastor/charts/loki/templates/ingester/hpa.yaml new file mode 100644 index 0000000..de35d67 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/hpa.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.autoscaling.enabled (or (not .Values.ingester.zoneAwareReplication.enabled) .Values.ingester.zoneAwareReplication.migration.enabled) }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.ingesterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.ingesterFullname" . }} + minReplicas: {{ .Values.ingester.autoscaling.minReplicas }} + maxReplicas: {{ .Values.ingester.autoscaling.maxReplicas }} + metrics: + {{- with .Values.ingester.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.ingester.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.ingester.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.ingester.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.ingester.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ingester/poddisruptionbudget-ingester-rollout.yaml b/charts/mayastor/charts/loki/templates/ingester/poddisruptionbudget-ingester-rollout.yaml new file mode 100644 index 0000000..4c1b133 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/poddisruptionbudget-ingester-rollout.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.ingester.replicas) 1) (.Values.ingester.zoneAwareReplication.enabled) }} +{{- if kindIs "invalid" .Values.ingester.maxUnavailable }} +{{- fail "`.Values.ingester.maxUnavailable` must be set when `.Values.ingester.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.ingesterFullname" . }}-rollout + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + {{- with .Values.ingester.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ingester/poddisruptionbudget-ingester.yaml b/charts/mayastor/charts/loki/templates/ingester/poddisruptionbudget-ingester.yaml new file mode 100644 index 0000000..f5c4838 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/poddisruptionbudget-ingester.yaml @@ -0,0 +1,27 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.ingester.replicas) 1) (or (not .Values.ingester.zoneAwareReplication.enabled) .Values.ingester.zoneAwareReplication.migration.enabled) }} +{{- if kindIs "invalid" .Values.ingester.maxUnavailable }} +{{- fail "`.Values.ingester.maxUnavailable` must be set when `.Values.ingester.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.ingesterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.ingesterSelectorLabels" . | nindent 6 }} + {{/* zone aware ingesters get their own pod disruption budget, ignore them here */}} + matchExpressions: + - key: rollout-group + operator: NotIn + values: + - '{{ include "loki.prefixRolloutGroup" . }}ingester' + {{- with .Values.ingester.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ingester/service-ingester-headless.yaml b/charts/mayastor/charts/loki/templates/ingester/service-ingester-headless.yaml new file mode 100644 index 0000000..8a8b92f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/service-ingester-headless.yaml @@ -0,0 +1,35 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (or (not .Values.ingester.zoneAwareReplication.enabled) .Values.ingester.zoneAwareReplication.migration.enabled) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.ingesterFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterSelectorLabels" . | nindent 4 }} + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.ingester.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.ingester.appProtocol.grpc }} + appProtocol: {{ .Values.ingester.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.ingesterSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/ingester/service-ingester-zone-a-headless.yaml b/charts/mayastor/charts/loki/templates/ingester/service-ingester-zone-a-headless.yaml new file mode 100644 index 0000000..380ed09 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/service-ingester-zone-a-headless.yaml @@ -0,0 +1,38 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.zoneAwareReplication.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-a-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + {{- with .Values.ingester.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.ingester.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.ingester.appProtocol.grpc }} + appProtocol: {{ .Values.ingester.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.ingesterSelectorLabels" . | nindent 4 }} + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-a + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/ingester/service-ingester-zone-b-headless.yaml b/charts/mayastor/charts/loki/templates/ingester/service-ingester-zone-b-headless.yaml new file mode 100644 index 0000000..00d851f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/service-ingester-zone-b-headless.yaml @@ -0,0 +1,38 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.zoneAwareReplication.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-b-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + {{- with .Values.ingester.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.ingester.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.ingester.appProtocol.grpc }} + appProtocol: {{ .Values.ingester.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.ingesterSelectorLabels" . | nindent 4 }} + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-b + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/ingester/service-ingester-zone-c-headless.yaml b/charts/mayastor/charts/loki/templates/ingester/service-ingester-zone-c-headless.yaml new file mode 100644 index 0000000..0bacdbc --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/service-ingester-zone-c-headless.yaml @@ -0,0 +1,38 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.zoneAwareReplication.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-c-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + {{- with .Values.ingester.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.ingester.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.ingester.appProtocol.grpc }} + appProtocol: {{ .Values.ingester.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.ingesterSelectorLabels" . | nindent 4 }} + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-c + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/ingester/service-ingester.yaml b/charts/mayastor/charts/loki/templates/ingester/service-ingester.yaml new file mode 100644 index 0000000..94d6f83 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/service-ingester.yaml @@ -0,0 +1,36 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (or (not .Values.ingester.zoneAwareReplication.enabled) .Values.ingester.zoneAwareReplication.migration.enabled) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.ingesterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + {{- with .Values.ingester.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.ingester.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.ingester.appProtocol.grpc }} + appProtocol: {{ .Values.ingester.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.ingesterSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/ingester/statefulset-ingester-zone-a.yaml b/charts/mayastor/charts/loki/templates/ingester/statefulset-ingester-zone-a.yaml new file mode 100644 index 0000000..9b21dec --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/statefulset-ingester-zone-a.yaml @@ -0,0 +1,233 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.zoneAwareReplication.enabled }} +{{- $replicas := (include "loki.ingester.replicaCount" .) -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-a + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-a + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + annotations: + rollout-max-unavailable: "{{ include "loki.ingester.maxUnavailable" (dict "ctx" . "replicas" $replicas)}}" + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneA.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.ingester.autoscaling.enabled }} + replicas: {{ $replicas }} +{{- end }} + podManagementPolicy: Parallel + serviceName: {{ include "loki.ingesterFullname" . }}-zone-a + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.ingester.persistence.enableStatefulSetAutoDeletePVC) }} + {{/* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.ingester.persistence.whenDeleted }} + whenScaled: {{ .Values.ingester.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.ingesterSelectorLabels" . | nindent 6 }} + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-a + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester +{{- with .Values.ingester.updateStrategy }} + updateStrategy: + {{- tpl (. | toYaml) $ | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneA.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.ingesterLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-a + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + {{- with merge (dict) .Values.loki.podLabels .Values.ingester.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.ingester.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.ingesterPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.ingester.terminationGracePeriodSeconds }} + {{- with .Values.ingester.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: ingester + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.ingester.command }} + command: + - {{ coalesce .Values.ingester.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -ingester.availability-zone=zone-a + - -ingester.unregister-on-shutdown=false + - -ingester.tokens-file-path=/var/loki/ring-tokens + - -target=ingester + {{- with (concat .Values.global.extraArgs .Values.ingester.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.ingester.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.ingester.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.ingester.readinessProbe" . | nindent 10 }} + {{- include "loki.ingester.livenessProbe" . | nindent 10 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.ingester.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.ingester.extraContainers }} + {{- toYaml .Values.ingester.extraContainers | nindent 8}} + {{- end }} + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: rollout-group + operator: In + values: + - {{ include "loki.prefixRolloutGroup" . }}ingester + - key: name + operator: NotIn + values: + - {{ include "loki.prefixIngesterName" . }}ingester-zone-a + topologyKey: kubernetes.io/hostname + {{- with .Values.ingester.zoneAwareReplication.zoneA.extraAffinity }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneA.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.ingester.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.ingester.persistence.enabled }} + - name: data + emptyDir: {} + {{- else if .Values.ingester.persistence.inMemory }} + - name: data + {{- if .Values.ingester.persistence.inMemory }} + emptyDir: + medium: Memory + {{- end }} + {{- if .Values.ingester.persistence.size }} + sizeLimit: {{ .Values.ingester.persistence.size }} + {{- end }} + {{- else }} + volumeClaimTemplates: + {{- range .Values.ingester.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ingester/statefulset-ingester-zone-b.yaml b/charts/mayastor/charts/loki/templates/ingester/statefulset-ingester-zone-b.yaml new file mode 100644 index 0000000..0b79c05 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/statefulset-ingester-zone-b.yaml @@ -0,0 +1,233 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.zoneAwareReplication.enabled }} +{{- $replicas := (include "loki.ingester.replicaCount" .) -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-b + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-b + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + annotations: + rollout-max-unavailable: "{{ include "loki.ingester.maxUnavailable" (dict "ctx" . "replicas" $replicas)}}" + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneB.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.ingester.autoscaling.enabled }} + replicas: {{ $replicas }} +{{- end }} + podManagementPolicy: Parallel + serviceName: {{ include "loki.ingesterFullname" . }}-zone-b + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.ingester.persistence.enableStatefulSetAutoDeletePVC) }} + {{/* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.ingester.persistence.whenDeleted }} + whenScaled: {{ .Values.ingester.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.ingesterSelectorLabels" . | nindent 6 }} + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-b + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester +{{- with .Values.ingester.updateStrategy }} + updateStrategy: + {{- tpl (. | toYaml) $ | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneB.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.ingesterLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-b + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + {{- with merge (dict) .Values.ingester.podLabels .Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.ingester.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.ingesterPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.ingester.terminationGracePeriodSeconds }} + {{- with .Values.ingester.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: ingester + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.ingester.command }} + command: + - {{ coalesce .Values.ingester.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -ingester.availability-zone=zone-b + - -ingester.unregister-on-shutdown=false + - -ingester.tokens-file-path=/var/loki/ring-tokens + - -target=ingester + {{- with (concat .Values.global.extraArgs .Values.ingester.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.ingester.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.ingester.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.ingester.readinessProbe" . | nindent 10 }} + {{- include "loki.ingester.livenessProbe" . | nindent 10 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.ingester.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.ingester.extraContainers }} + {{- toYaml .Values.ingester.extraContainers | nindent 8}} + {{- end }} + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: rollout-group + operator: In + values: + - {{ include "loki.prefixRolloutGroup" . }}ingester + - key: name + operator: NotIn + values: + - {{ include "loki.prefixIngesterName" . }}ingester-zone-b + topologyKey: kubernetes.io/hostname + {{- with .Values.ingester.zoneAwareReplication.zoneB.extraAffinity }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneB.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.ingester.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.ingester.persistence.enabled }} + - name: data + emptyDir: {} + {{- else if .Values.ingester.persistence.inMemory }} + - name: data + {{- if .Values.ingester.persistence.inMemory }} + emptyDir: + medium: Memory + {{- end }} + {{- if .Values.ingester.persistence.size }} + sizeLimit: {{ .Values.ingester.persistence.size }} + {{- end }} + {{- else }} + volumeClaimTemplates: + {{- range .Values.ingester.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ingester/statefulset-ingester-zone-c.yaml b/charts/mayastor/charts/loki/templates/ingester/statefulset-ingester-zone-c.yaml new file mode 100644 index 0000000..140bf7a --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/statefulset-ingester-zone-c.yaml @@ -0,0 +1,233 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ingester.zoneAwareReplication.enabled }} +{{- $replicas := (include "loki.ingester.replicaCount" .) -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.ingesterFullname" . }}-zone-c + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-c + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + annotations: + rollout-max-unavailable: "{{ include "loki.ingester.maxUnavailable" (dict "ctx" . "replicas" $replicas)}}" + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneC.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.ingester.autoscaling.enabled }} + replicas: {{ $replicas }} +{{- end }} + podManagementPolicy: Parallel + serviceName: {{ include "loki.ingesterFullname" . }}-zone-c + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.ingester.persistence.enableStatefulSetAutoDeletePVC) }} + {{/* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.ingester.persistence.whenDeleted }} + whenScaled: {{ .Values.ingester.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.ingesterSelectorLabels" . | nindent 6 }} + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-c + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester +{{- with .Values.ingester.updateStrategy }} + updateStrategy: + {{- tpl (. | toYaml) $ | nindent 4 }} +{{- end }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneC.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.ingesterLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + name: {{ include "loki.prefixIngesterName" . }}ingester-zone-c + rollout-group: {{ include "loki.prefixRolloutGroup" . }}ingester + {{- with merge (dict) .Values.ingester.podLabels .Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.ingester.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.ingesterPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.ingester.terminationGracePeriodSeconds }} + {{- with .Values.ingester.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: ingester + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.ingester.command }} + command: + - {{ coalesce .Values.ingester.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -ingester.availability-zone=zone-c + - -ingester.unregister-on-shutdown=false + - -ingester.tokens-file-path=/var/loki/ring-tokens + - -target=ingester + {{- with (concat .Values.global.extraArgs .Values.ingester.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.ingester.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.ingester.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.ingester.readinessProbe" . | nindent 10 }} + {{- include "loki.ingester.livenessProbe" . | nindent 10 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.ingester.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.ingester.extraContainers }} + {{- toYaml .Values.ingester.extraContainers | nindent 8}} + {{- end }} + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: rollout-group + operator: In + values: + - {{ include "loki.prefixIngesterName" . }}ingester + - key: name + operator: NotIn + values: + - {{ include "loki.prefixIngesterName" . }}ingester-zone-c + topologyKey: kubernetes.io/hostname + {{- with .Values.ingester.zoneAwareReplication.zoneC.extraAffinity }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.zoneAwareReplication.zoneC.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.ingester.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.ingester.persistence.enabled }} + - name: data + emptyDir: {} + {{- else if .Values.ingester.persistence.inMemory }} + - name: data + {{- if .Values.ingester.persistence.inMemory }} + emptyDir: + medium: Memory + {{- end }} + {{- if .Values.ingester.persistence.size }} + sizeLimit: {{ .Values.ingester.persistence.size }} + {{- end }} + {{- else }} + volumeClaimTemplates: + {{- range .Values.ingester.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ingester/statefulset-ingester.yaml b/charts/mayastor/charts/loki/templates/ingester/statefulset-ingester.yaml new file mode 100644 index 0000000..9055fe2 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingester/statefulset-ingester.yaml @@ -0,0 +1,204 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (or (not .Values.ingester.zoneAwareReplication.enabled) .Values.ingester.zoneAwareReplication.migration.enabled) }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.ingesterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.ingesterLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.ingester.autoscaling.enabled }} + replicas: {{ .Values.ingester.replicas }} +{{- end }} + podManagementPolicy: Parallel +{{- with .Values.ingester.updateStrategy }} + updateStrategy: + {{- tpl (. | toYaml) $ | nindent 4 }} +{{- end }} + serviceName: {{ include "loki.ingesterFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.ingester.persistence.enableStatefulSetAutoDeletePVC) }} + {{/* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.ingester.persistence.whenDeleted }} + whenScaled: {{ .Values.ingester.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.ingesterSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.ingesterLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.ingester.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.ingester.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.ingesterPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.ingester.terminationGracePeriodSeconds }} + {{- with .Values.ingester.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: ingester + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.ingester.command }} + command: + - {{ coalesce .Values.ingester.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -ingester.availability-zone=zone-default + - -target=ingester + {{- with (concat .Values.global.extraArgs .Values.ingester.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.ingester.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.ingester.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.ingester.readinessProbe" . | nindent 10 }} + {{- include "loki.ingester.livenessProbe" . | nindent 10 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.ingester.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.ingester.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.ingester.extraContainers }} + {{- toYaml .Values.ingester.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.ingester.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ingester.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.ingester.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.ingester.persistence.enabled }} + - name: data + emptyDir: { } + {{- else if .Values.ingester.persistence.inMemory }} + - name: data + {{- if .Values.ingester.persistence.inMemory }} + emptyDir: + medium: Memory + {{- end }} + {{- if .Values.ingester.persistence.size }} + sizeLimit: {{ .Values.ingester.persistence.size }} + {{- end }} + {{- else }} + volumeClaimTemplates: + {{- range .Values.ingester.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ingress.yaml b/charts/mayastor/charts/loki/templates/ingress.yaml new file mode 100644 index 0000000..ddbcf7f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ingress.yaml @@ -0,0 +1,40 @@ +{{- if .Values.ingress.enabled }} +{{- $ingressSupportsIngressClassName := eq (include "loki.ingress.supportsIngressClassName" .) "true" -}} +apiVersion: {{ include "loki.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ include "loki.fullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end -}} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ tpl . $ | quote }} + {{- end }} + {{- with .secretName }} + secretName: {{ . }} + {{- end }} + {{- end }} + {{- end }} + rules: + {{- range $.Values.ingress.hosts }} + - host: {{ tpl . $ | quote }} + http: + paths: + {{- include "loki.ingress.servicePaths" $ | indent 10}} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/loki-canary/_helpers.tpl b/charts/mayastor/charts/loki/templates/loki-canary/_helpers.tpl new file mode 100644 index 0000000..01e588c --- /dev/null +++ b/charts/mayastor/charts/loki/templates/loki-canary/_helpers.tpl @@ -0,0 +1,40 @@ +{{/* +canary fullname +*/}} +{{- define "loki-canary.fullname" -}} +{{ include "loki.name" . }}-canary +{{- end }} + +{{/* +canary common labels +*/}} +{{- define "loki-canary.labels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: canary +{{- end }} + +{{/* +canary selector labels +*/}} +{{- define "loki-canary.selectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: canary +{{- end }} + +{{/* +Docker image name for loki-canary +*/}} +{{- define "loki-canary.image" -}} +{{- $dict := dict "service" .Values.lokiCanary.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}} +{{- include "loki.baseImage" $dict -}} +{{- end -}} + +{{/* +canary priority class name +*/}} +{{- define "loki-canary.priorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.lokiCanary.priorityClassName .Values.read.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/loki-canary/daemonset.yaml b/charts/mayastor/charts/loki/templates/loki-canary/daemonset.yaml new file mode 100644 index 0000000..dc5c629 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/loki-canary/daemonset.yaml @@ -0,0 +1,123 @@ +{{- with .Values.lokiCanary -}} +{{- if .enabled -}} +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "loki-canary.fullname" $ }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki-canary.labels" $ | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki-canary.selectorLabels" $ | nindent 6 }} + {{- with .updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki-canary.selectorLabels" $ | nindent 8 }} + {{- with .podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki-canary.fullname" $ }} + {{- with $.Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki-canary.priorityClassName" $ | nindent 6 }} + securityContext: + {{- toYaml $.Values.loki.podSecurityContext | nindent 8 }} + containers: + - name: loki-canary + image: {{ include "loki-canary.image" $ }} + imagePullPolicy: {{ $.Values.loki.image.pullPolicy }} + args: + - -addr={{- include "loki.host" $ }} + - -labelname={{ .labelname }} + - -labelvalue=$(POD_NAME) + {{- if $.Values.enterprise.enabled }} + - -user=$(USER) + - -tenant-id=$(USER) + - -pass=$(PASS) + {{- else if $.Values.loki.auth_enabled }} + - -user={{ $.Values.monitoring.selfMonitoring.tenant.name }} + - -tenant-id={{ $.Values.monitoring.selfMonitoring.tenant.name }} + - -pass={{ $.Values.monitoring.selfMonitoring.tenant.password }} + {{- end }} + {{- if .push }} + - -push=true + {{- end }} + {{- with .extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml $.Values.loki.containerSecurityContext | nindent 12 }} + volumeMounts: + {{- with $.Values.lokiCanary.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3500 + protocol: TCP + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + {{ if $.Values.enterprise.enabled }} + - name: USER + valueFrom: + secretKeyRef: + name: {{ include "enterprise-logs.selfMonitoringTenantSecret" $ }} + key: username + - name: PASS + valueFrom: + secretKeyRef: + name: {{ include "enterprise-logs.selfMonitoringTenantSecret" $ }} + key: password + {{- end -}} + {{- with .extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + readinessProbe: + httpGet: + path: /metrics + port: http-metrics + initialDelaySeconds: 15 + timeoutSeconds: 1 + {{- with .resources}} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + {{- with $.Values.lokiCanary.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/loki-canary/service.yaml b/charts/mayastor/charts/loki/templates/loki-canary/service.yaml new file mode 100644 index 0000000..38022a3 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/loki-canary/service.yaml @@ -0,0 +1,34 @@ +{{- with .Values.lokiCanary -}} +{{- if .enabled -}} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki-canary.fullname" $ }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki-canary.labels" $ | nindent 4 }} + {{- with $.Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + annotations: + {{- with $.Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3500 + targetPort: http-metrics + protocol: TCP + selector: + {{- include "loki-canary.selectorLabels" $ | nindent 4 }} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/loki-canary/serviceaccount.yaml b/charts/mayastor/charts/loki/templates/loki-canary/serviceaccount.yaml new file mode 100644 index 0000000..2c1f79a --- /dev/null +++ b/charts/mayastor/charts/loki/templates/loki-canary/serviceaccount.yaml @@ -0,0 +1,21 @@ +{{- with .Values.lokiCanary -}} +{{- if .enabled -}} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "loki-canary.fullname" $ }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki-canary.labels" $ | nindent 4 }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ $.Values.serviceAccount.automountServiceAccountToken }} +{{- with $.Values.serviceAccount.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/memcached/_memcached-statefulset.tpl b/charts/mayastor/charts/loki/templates/memcached/_memcached-statefulset.tpl new file mode 100644 index 0000000..cb798e5 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/memcached/_memcached-statefulset.tpl @@ -0,0 +1,180 @@ +{{/* +memcached StatefulSet +Params: + ctx = . context + valuesSection = name of the section in values.yaml + component = name of the component +valuesSection and component are specified separately because helm prefers camelcase for naming convetion and k8s components are named with snake case. +*/}} +{{- define "loki.memcached.statefulSet" -}} +{{ with (index $.ctx.Values $.valuesSection) }} +{{- if .enabled -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.resourceName" (dict "ctx" $.ctx "component" $.component) }} + labels: + {{- include "loki.labels" $.ctx | nindent 4 }} + app.kubernetes.io/component: "memcached-{{ $.component }}" + name: "memcached-{{ $.component }}" + annotations: + {{- toYaml .annotations | nindent 4 }} + namespace: {{ $.ctx.Release.Namespace | quote }} +spec: + podManagementPolicy: {{ .podManagementPolicy }} + replicas: {{ .replicas }} + selector: + matchLabels: + {{- include "loki.selectorLabels" $.ctx | nindent 6 }} + app.kubernetes.io/component: "memcached-{{ $.component }}" + name: "memcached-{{ $.component }}" + updateStrategy: + {{- toYaml .statefulStrategy | nindent 4 }} + serviceName: {{ template "loki.fullname" $.ctx }}-{{ $.component }} + + template: + metadata: + labels: + {{- include "loki.selectorLabels" $.ctx | nindent 8 }} + app.kubernetes.io/component: "memcached-{{ $.component }}" + name: "memcached-{{ $.component }}" + {{- with $.ctx.Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{- with $.ctx.Values.global.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + + spec: + serviceAccountName: {{ template "loki.serviceAccountName" $.ctx }} + {{- if .priorityClassName }} + priorityClassName: {{ .priorityClassName }} + {{- end }} + securityContext: + {{- toYaml $.ctx.Values.memcached.podSecurityContext | nindent 8 }} + initContainers: + {{- toYaml .initContainers | nindent 8 }} + nodeSelector: + {{- toYaml .nodeSelector | nindent 8 }} + affinity: + {{- toYaml .affinity | nindent 8 }} + topologySpreadConstraints: + {{- toYaml .topologySpreadConstraints | nindent 8 }} + tolerations: + {{- toYaml .tolerations | nindent 8 }} + terminationGracePeriodSeconds: {{ .terminationGracePeriodSeconds }} + {{- with $.ctx.Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .extraVolumes }} + volumes: + {{- toYaml .extraVolumes | nindent 8 }} + {{- end }} + containers: + {{- if .extraContainers }} + {{ toYaml .extraContainers | nindent 8 }} + {{- end }} + - name: memcached + {{- with $.ctx.Values.memcached.image }} + image: {{ .repository }}:{{ .tag }} + imagePullPolicy: {{ .pullPolicy }} + {{- end }} + resources: + {{- if .resources }} + {{- toYaml .resources | nindent 12 }} + {{- else }} + {{- /* Calculate requested memory as round(allocatedMemory * 1.2). But with integer built-in operators. */}} + {{- $requestMemory := div (add (mul .allocatedMemory 12) 5) 10 }} + limits: + memory: {{ $requestMemory }}Mi + requests: + cpu: 500m + memory: {{ $requestMemory }}Mi + {{- end }} + ports: + - containerPort: {{ .port }} + name: client + {{- /* Calculate storage size as round(.persistence.storageSize * 0.9). But with integer built-in operators. */}} + {{- $persistenceSize := (div (mul (trimSuffix "Gi" .persistence.storageSize | trimSuffix "G") 9) 10 ) }} + args: + - -m {{ .allocatedMemory }} + - --extended=modern,track_sizes{{ if .persistence.enabled }},ext_path={{ .persistence.mountPath }}/file:{{ $persistenceSize }}G,ext_wbuf_size=16{{ end }}{{ with .extraExtendedOptions }},{{ . }}{{ end }} + - -I {{ .maxItemMemory }}m + - -c {{ .connectionLimit }} + - -v + - -u {{ .port }} + {{- range $key, $value := .extraArgs }} + - "-{{ $key }}{{ if $value }} {{ $value }}{{ end }}" + {{- end }} + env: + {{- with $.ctx.Values.global.extraEnv }} + {{ toYaml . | nindent 12 }} + {{- end }} + envFrom: + {{- with $.ctx.Values.global.extraEnvFrom }} + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml $.ctx.Values.memcached.containerSecurityContext | nindent 12 }} + {{- if or .persistence.enabled .extraVolumeMounts }} + volumeMounts: + {{- if .persistence.enabled }} + - name: data + mountPath: {{ .persistence.mountPath }} + {{- end }} + {{- if .extraVolumeMounts }} + {{- toYaml .extraVolumeMounts | nindent 12 }} + {{- end }} + {{- end }} + + {{- if $.ctx.Values.memcachedExporter.enabled }} + - name: exporter + {{- with $.ctx.Values.memcachedExporter.image }} + image: {{ .repository}}:{{ .tag }} + imagePullPolicy: {{ .pullPolicy }} + {{- end }} + ports: + - containerPort: 9150 + name: http-metrics + args: + - "--memcached.address=localhost:{{ .port }}" + - "--web.listen-address=0.0.0.0:9150" + {{- range $key, $value := $.ctx.Values.memcachedExporter.extraArgs }} + - "--{{ $key }}{{ if $value }}={{ $value }}{{ end }}" + {{- end }} + resources: + {{- toYaml $.ctx.Values.memcachedExporter.resources | nindent 12 }} + securityContext: + {{- toYaml $.ctx.Values.memcachedExporter.containerSecurityContext | nindent 12 }} + {{- if .extraVolumeMounts }} + volumeMounts: + {{- toYaml .extraVolumeMounts | nindent 12 }} + {{- end }} + {{- end }} + {{- if .persistence.enabled }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + spec: + accessModes: [ "ReadWriteOnce" ] + {{- with .persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .persistence.storageSize | quote }} + {{- end }} +{{- end -}} +{{- end -}} +{{- end -}} + diff --git a/charts/mayastor/charts/loki/templates/memcached/_memcached-svc.tpl b/charts/mayastor/charts/loki/templates/memcached/_memcached-svc.tpl new file mode 100644 index 0000000..8574151 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/memcached/_memcached-svc.tpl @@ -0,0 +1,42 @@ +{{/* +memcached Service +Params: + ctx = . context + valuesSection = name of the section in values.yaml + component = name of the component +valuesSection and component are specified separately because helm prefers camelcase for naming convetion and k8s components are named with snake case. +*/}} +{{- define "loki.memcached.service" -}} +{{ with (index $.ctx.Values $.valuesSection) }} +{{- if .enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.resourceName" (dict "ctx" $.ctx "component" $.component) }} + labels: + {{- include "loki.labels" $.ctx | nindent 4 }} + app.kubernetes.io/component: "memcached-{{ $.component }}" + {{- with .service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- toYaml .service.annotations | nindent 4 }} + namespace: {{ $.ctx.Release.Namespace | quote }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: memcached-client + port: {{ .port }} + targetPort: {{ .port }} + {{ if $.ctx.Values.memcachedExporter.enabled -}} + - name: http-metrics + port: 9150 + targetPort: 9150 + {{ end }} + selector: + {{- include "loki.selectorLabels" $.ctx | nindent 4 }} + app.kubernetes.io/component: "memcached-{{ $.component }}" +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/monitoring/_helpers-monitoring.tpl b/charts/mayastor/charts/loki/templates/monitoring/_helpers-monitoring.tpl new file mode 100644 index 0000000..cb693e4 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/monitoring/_helpers-monitoring.tpl @@ -0,0 +1,47 @@ +{{/* +Client definition for LogsInstance +*/}} +{{- define "loki.logsInstanceClient" -}} +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- $url := printf "http://%s.%s.svc.%s:%s/loki/api/v1/push" (include "loki.writeFullname" .) .Release.Namespace .Values.global.clusterDomain ( .Values.loki.server.http_listen_port | toString ) }} +{{- if $isSingleBinary }} + {{- $url = printf "http://%s.%s.svc.%s:%s/loki/api/v1/push" (include "loki.singleBinaryFullname" .) .Release.Namespace .Values.global.clusterDomain ( .Values.loki.server.http_listen_port | toString ) }} +{{- else if .Values.gateway.enabled -}} + {{- $url = printf "http://%s.%s.svc.%s/loki/api/v1/push" (include "loki.gatewayFullname" .) .Release.Namespace .Values.global.clusterDomain }} +{{- end -}} +- url: {{ $url }} + externalLabels: + cluster: {{ include "loki.clusterLabel" . }} + {{- if .Values.enterprise.enabled }} + basicAuth: + username: + name: {{ include "enterprise-logs.selfMonitoringTenantSecret" . }} + key: username + password: + name: {{ include "enterprise-logs.selfMonitoringTenantSecret" . }} + key: password + {{- else if .Values.loki.auth_enabled }} + tenantId: {{ .Values.monitoring.selfMonitoring.tenant.name | quote }} + {{- end }} +{{- end -}} + +{{/* +Convert a recording rule group to yaml +*/}} +{{- define "loki.ruleGroupToYaml" -}} +{{- range . }} +- name: {{ .name }} + rules: + {{- toYaml .rules | nindent 4 }} +{{- end }} +{{- end }} + +{{/* +GrafanaAgent priority class name +*/}} +{{- define "grafana-agent.priorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.monitoring.selfMonitoring.grafanaAgent.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/monitoring/dashboards/_helpers-dashboards.tpl b/charts/mayastor/charts/loki/templates/monitoring/dashboards/_helpers-dashboards.tpl new file mode 100644 index 0000000..00fd722 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/monitoring/dashboards/_helpers-dashboards.tpl @@ -0,0 +1,6 @@ +{{/* +dashboards name +*/}} +{{- define "loki.dashboardsName" -}} +{{ include "loki.name" . }}-dashboards +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/monitoring/dashboards/configmap-1.yaml b/charts/mayastor/charts/loki/templates/monitoring/dashboards/configmap-1.yaml new file mode 100644 index 0000000..6352f25 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/monitoring/dashboards/configmap-1.yaml @@ -0,0 +1,30 @@ +{{- with .Values.monitoring.dashboards }} +{{- if .enabled }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "loki.dashboardsName" $ }}-1 + namespace: {{ .namespace | default $.Release.Namespace }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + "loki-chunks.json": | + {{ $.Files.Get "src/dashboards/loki-chunks.json" | fromJson | toJson }} + "loki-deletion.json": | + {{ $.Files.Get "src/dashboards/loki-deletion.json" | fromJson | toJson }} + "loki-logs.json": | + {{ $.Files.Get "src/dashboards/loki-logs.json" | fromJson | toJson }} + "loki-mixin-recording-rules.json": | + {{ $.Files.Get "src/dashboards/loki-mixin-recording-rules.json" | fromJson | toJson }} + "loki-operational.json": | + {{ $.Files.Get "src/dashboards/loki-operational.json" | fromJson | toJson }} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/monitoring/dashboards/configmap-2.yaml b/charts/mayastor/charts/loki/templates/monitoring/dashboards/configmap-2.yaml new file mode 100644 index 0000000..67d3cf4 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/monitoring/dashboards/configmap-2.yaml @@ -0,0 +1,30 @@ +{{- with .Values.monitoring.dashboards }} +{{- if .enabled }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "loki.dashboardsName" $ }}-2 + namespace: {{ .namespace | default $.Release.Namespace }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + "loki-reads-resources.json": | + {{ $.Files.Get "src/dashboards/loki-reads-resources.json" | fromJson | toJson }} + "loki-reads.json": | + {{ $.Files.Get "src/dashboards/loki-reads.json" | fromJson | toJson }} + "loki-retention.json": | + {{ $.Files.Get "src/dashboards/loki-retention.json" | fromJson | toJson }} + "loki-writes-resources.json": | + {{ $.Files.Get "src/dashboards/loki-writes-resources.json" | fromJson | toJson }} + "loki-writes.json": | + {{ $.Files.Get "src/dashboards/loki-writes.json" | fromJson | toJson }} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/monitoring/grafana-agent.yaml b/charts/mayastor/charts/loki/templates/monitoring/grafana-agent.yaml new file mode 100644 index 0000000..a047e5f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/monitoring/grafana-agent.yaml @@ -0,0 +1,100 @@ +{{- if .Values.monitoring.selfMonitoring.enabled }} +{{- with .Values.monitoring.selfMonitoring.grafanaAgent }} +apiVersion: monitoring.grafana.com/v1alpha1 +kind: GrafanaAgent +metadata: + name: {{ include "loki.fullname" $ }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + serviceAccountName: {{ include "loki.fullname" $ }}-grafana-agent + enableConfigReadAPI: {{ .enableConfigReadAPI }} + {{- include "grafana-agent.priorityClassName" $ | nindent 2 }} + logs: + instanceSelector: + matchLabels: + {{- include "loki.selectorLabels" $ | nindent 8 }} + {{- with $.Values.monitoring.serviceMonitor}} + {{- if .metricsInstance.remoteWrite}} + metrics: + instanceSelector: + matchLabels: + {{- include "loki.selectorLabels" $ | nindent 8 }} + {{- end }} + {{- end }} + {{- with .resources }} + resources: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .tolerations }} + tolerations: + {{- toYaml . | nindent 4 }} + {{- end }} + +--- + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "loki.fullname" $ }}-grafana-agent + namespace: {{ .namespace | default $.Release.Namespace }} + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "loki.fullname" $ }}-grafana-agent +rules: +- apiGroups: + - "" + resources: + - nodes + - nodes/proxy + - nodes/metrics + - services + - endpoints + - pods + - events + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- nonResourceURLs: + - /metrics + - /metrics/cadvisor + verbs: + - get + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "loki.fullname" $ }}-grafana-agent +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "loki.fullname" $ }}-grafana-agent +subjects: +- kind: ServiceAccount + name: {{ include "loki.fullname" $ }}-grafana-agent + namespace: {{ .namespace | default $.Release.Namespace }} +{{- end}} +{{- end}} diff --git a/charts/mayastor/charts/loki/templates/monitoring/logs-instance.yaml b/charts/mayastor/charts/loki/templates/monitoring/logs-instance.yaml new file mode 100644 index 0000000..5ae1917 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/monitoring/logs-instance.yaml @@ -0,0 +1,30 @@ +{{- if .Values.monitoring.selfMonitoring.enabled }} +{{- with .Values.monitoring.selfMonitoring.logsInstance }} +apiVersion: monitoring.grafana.com/v1alpha1 +kind: LogsInstance +metadata: + name: {{ include "loki.fullname" $ }} + namespace: {{ $.Release.Namespace }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + clients: + {{- include "loki.logsInstanceClient" $ | nindent 4}} + {{- with .clients}} + {{- toYaml . | nindent 4 }} + {{- end }} + + podLogsNamespaceSelector: {} + + podLogsSelector: + matchLabels: + {{- include "loki.selectorLabels" $ | nindent 6 }} +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/charts/mayastor/charts/loki/templates/monitoring/loki-alerts.yaml b/charts/mayastor/charts/loki/templates/monitoring/loki-alerts.yaml new file mode 100644 index 0000000..f3333df --- /dev/null +++ b/charts/mayastor/charts/loki/templates/monitoring/loki-alerts.yaml @@ -0,0 +1,22 @@ +{{- with .Values.monitoring.rules }} +{{- if and ($.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/PrometheusRule") .enabled .alerting }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "loki.fullname" $ }}-loki-alerts + namespace: {{ .namespace | default $.Release.Namespace }} +spec: + groups: + {{- include "loki.ruleGroupToYaml" (tpl ($.Files.Get "src/alerts.yaml.tpl") $ | fromYaml).groups | indent 4 }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/monitoring/loki-rules.yaml b/charts/mayastor/charts/loki/templates/monitoring/loki-rules.yaml new file mode 100644 index 0000000..f9eb392 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/monitoring/loki-rules.yaml @@ -0,0 +1,23 @@ +{{- with .Values.monitoring.rules }} +{{- if and ($.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/PrometheusRule") .enabled }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "loki.fullname" $ }}-loki-rules + namespace: {{ .namespace | default $.Release.Namespace }} +spec: + groups: + {{- include "loki.ruleGroupToYaml" (tpl ($.Files.Get "src/rules.yaml.tpl") $ | fromYaml).groups | indent 4 }} + {{- include "loki.ruleGroupToYaml" .additionalGroups | indent 4 }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/monitoring/metrics-instance.yaml b/charts/mayastor/charts/loki/templates/monitoring/metrics-instance.yaml new file mode 100644 index 0000000..82102c0 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/monitoring/metrics-instance.yaml @@ -0,0 +1,30 @@ +{{- if .Values.monitoring.serviceMonitor.enabled }} +{{- with .Values.monitoring.serviceMonitor.metricsInstance }} +{{- if and ($.Capabilities.APIVersions.Has "monitoring.grafana.com/v1alpha1/MetricsInstance") .enabled }} +apiVersion: monitoring.grafana.com/v1alpha1 +kind: MetricsInstance +metadata: + name: {{ include "loki.fullname" $ }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .remoteWrite}} + remoteWrite: + {{- toYaml . | nindent 4 }} + {{- end }} + + serviceMonitorNamespaceSelector: {} + + serviceMonitorSelector: + matchLabels: + {{- include "loki.selectorLabels" $ | nindent 6 }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/monitoring/pod-logs.yaml b/charts/mayastor/charts/loki/templates/monitoring/pod-logs.yaml new file mode 100644 index 0000000..317339d --- /dev/null +++ b/charts/mayastor/charts/loki/templates/monitoring/pod-logs.yaml @@ -0,0 +1,62 @@ +--- +{{- if .Values.monitoring.selfMonitoring.enabled }} +{{- with .Values.monitoring.selfMonitoring.podLogs }} +apiVersion: {{ .apiVersion }} +kind: PodLogs +metadata: + name: {{ include "loki.fullname" $ }} + namespace: {{ $.Release.Namespace }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + pipelineStages: + - cri: { } + {{- with .additionalPipelineStages }} + {{- toYaml . | nindent 4 }} + {{- end }} + relabelings: + - action: replace + sourceLabels: + - __meta_kubernetes_pod_node_name + targetLabel: __host__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + replacement: "$1" + separator: "-" + sourceLabels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app_kubernetes_io_component + targetLabel: __service__ + - action: replace + replacement: "$1" + separator: "/" + sourceLabels: + - __meta_kubernetes_namespace + - __service__ + targetLabel: job + - action: replace + sourceLabels: + - __meta_kubernetes_pod_container_name + targetLabel: container + - action: replace + replacement: "{{ include "loki.clusterLabel" $ }}" + targetLabel: cluster + {{- with .relabelings }} + {{- toYaml . | nindent 4 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ $.Release.Namespace }} + selector: + matchLabels: + {{- include "loki.selectorLabels" $ | nindent 6 }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/monitoring/servicemonitor.yaml b/charts/mayastor/charts/loki/templates/monitoring/servicemonitor.yaml new file mode 100644 index 0000000..856cee8 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/monitoring/servicemonitor.yaml @@ -0,0 +1,63 @@ +{{- with .Values.monitoring.serviceMonitor }} +{{- if and ($.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor") .enabled }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "loki.fullname" $ }} + namespace: {{ $.Release.Namespace }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "loki.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- include "loki.selectorLabels" $ | nindent 6 }} + matchExpressions: + - key: prometheus.io/service-monitor + operator: NotIn + values: + - "false" + endpoints: + - port: http-metrics + path: /metrics + {{- with .interval }} + interval: {{ . }} + {{- end }} + {{- with .scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + relabelings: + - sourceLabels: [job] + action: replace + replacement: "{{ $.Release.Namespace }}/$1" + targetLabel: job + - action: replace + replacement: "{{ include "loki.clusterLabel" $ }}" + targetLabel: cluster + {{- with .relabelings }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .scheme }} + scheme: {{ . }} + {{- end }} + {{- with .tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/networkpolicy.yaml b/charts/mayastor/charts/loki/templates/networkpolicy.yaml new file mode 100644 index 0000000..9286edb --- /dev/null +++ b/charts/mayastor/charts/loki/templates/networkpolicy.yaml @@ -0,0 +1,203 @@ +{{- if and (.Values.networkPolicy.enabled) (eq .Values.networkPolicy.flavor "kubernetes") }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-namespace-only + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Ingress + - Egress + podSelector: {} + egress: + - to: + - podSelector: {} + ingress: + - from: + - podSelector: {} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-dns + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Egress + podSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + egress: + - ports: + - port: dns + protocol: UDP + to: + - namespaceSelector: {} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-ingress + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Ingress + podSelector: + matchExpressions: + - key: app.kubernetes.io/component + operator: In + values: + {{- if .Values.gateway.enabled }} + - gateway + {{- else }} + - read + - write + {{- end }} + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + ingress: + - ports: + - port: http-metrics + protocol: TCP + {{- if .Values.networkPolicy.ingress.namespaceSelector }} + from: + - namespaceSelector: + {{- toYaml .Values.networkPolicy.ingress.namespaceSelector | nindent 12 }} + {{- if .Values.networkPolicy.ingress.podSelector }} + podSelector: + {{- toYaml .Values.networkPolicy.ingress.podSelector | nindent 12 }} + {{- end }} + {{- end }} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-ingress-metrics + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Ingress + podSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + ingress: + - ports: + - port: http-metrics + protocol: TCP + {{- if .Values.networkPolicy.metrics.cidrs }} + from: + {{- range $cidr := .Values.networkPolicy.metrics.cidrs }} + - ipBlock: + cidr: {{ $cidr }} + {{- end }} + {{- if .Values.networkPolicy.metrics.namespaceSelector }} + - namespaceSelector: + {{- toYaml .Values.networkPolicy.metrics.namespaceSelector | nindent 12 }} + {{- if .Values.networkPolicy.metrics.podSelector }} + podSelector: + {{- toYaml .Values.networkPolicy.metrics.podSelector | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-alertmanager + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Egress + podSelector: + matchLabels: + {{- include "loki.backendSelectorLabels" . | nindent 6 }} + egress: + - ports: + - port: {{ .Values.networkPolicy.alertmanager.port }} + protocol: TCP + {{- if .Values.networkPolicy.alertmanager.namespaceSelector }} + to: + - namespaceSelector: + {{- toYaml .Values.networkPolicy.alertmanager.namespaceSelector | nindent 12 }} + {{- if .Values.networkPolicy.alertmanager.podSelector }} + podSelector: + {{- toYaml .Values.networkPolicy.alertmanager.podSelector | nindent 12 }} + {{- end }} + {{- end }} + +{{- if .Values.networkPolicy.externalStorage.ports }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-external-storage + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Egress + podSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + egress: + - ports: + {{- range $port := .Values.networkPolicy.externalStorage.ports }} + - port: {{ $port }} + protocol: TCP + {{- end }} + {{- if .Values.networkPolicy.externalStorage.cidrs }} + to: + {{- range $cidr := .Values.networkPolicy.externalStorage.cidrs }} + - ipBlock: + cidr: {{ $cidr }} + {{- end }} + {{- end }} +{{- end }} + +{{- end }} + +{{- if and .Values.networkPolicy.discovery.port (eq .Values.networkPolicy.flavor "kubernetes") }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "loki.name" . }}-egress-discovery + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + policyTypes: + - Egress + podSelector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + egress: + - ports: + - port: {{ .Values.networkPolicy.discovery.port }} + protocol: TCP + {{- if .Values.networkPolicy.discovery.namespaceSelector }} + to: + - namespaceSelector: + {{- toYaml .Values.networkPolicy.discovery.namespaceSelector | nindent 12 }} + {{- if .Values.networkPolicy.discovery.podSelector }} + podSelector: + {{- toYaml .Values.networkPolicy.discovery.podSelector | nindent 12 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/overrides-exporter/_helpers-overrides-exporter.tpl b/charts/mayastor/charts/loki/templates/overrides-exporter/_helpers-overrides-exporter.tpl new file mode 100644 index 0000000..1baa60e --- /dev/null +++ b/charts/mayastor/charts/loki/templates/overrides-exporter/_helpers-overrides-exporter.tpl @@ -0,0 +1,32 @@ +{{/* +overrides-exporter fullname +*/}} +{{- define "loki.overridesExporterFullname" -}} +{{ include "loki.fullname" . }}-overrides-exporter +{{- end }} + +{{/* +overrides-exporter common labels +*/}} +{{- define "loki.overridesExporterLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: overrides-exporter +{{- end }} + +{{/* +overrides-exporter selector labels +*/}} +{{- define "loki.overridesExporterSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: overrides-exporter +{{- end }} + +{{/* +overrides-exporter priority class name +*/}} +{{- define "loki.overridesExporterPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.overridesExporter.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/overrides-exporter/deployment-overrides-exporter.yaml b/charts/mayastor/charts/loki/templates/overrides-exporter/deployment-overrides-exporter.yaml new file mode 100644 index 0000000..f214ce5 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/overrides-exporter/deployment-overrides-exporter.yaml @@ -0,0 +1,143 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.overridesExporter.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.overridesExporterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.overridesExporterLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.overridesExporter.replicas }} + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.overridesExporterSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.overridesExporter.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.overridesExporterLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.overridesExporter.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.overridesExporter.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.overridesExporter.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.overridesExporterPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.overridesExporter.terminationGracePeriodSeconds }} + containers: + - name: overrides-exporter + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.overridesExporter.command }} + command: + - {{ coalesce .Values.overridesExporter.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=overrides-exporter + {{- with (concat .Values.global.extraArgs .Values.overridesExporter.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.overridesExporter.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.overridesExporter.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.overridesExporter.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.overridesExporter.resources | nindent 12 }} + {{- if .Values.overridesExporter.extraContainers }} + {{- toYaml .Values.overridesExporter.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.overridesExporter.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.overridesExporter.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.overridesExporter.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.overridesExporter.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/overrides-exporter/poddisruptionbudget-overrides-exporter.yaml b/charts/mayastor/charts/loki/templates/overrides-exporter/poddisruptionbudget-overrides-exporter.yaml new file mode 100644 index 0000000..d8be6f4 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/overrides-exporter/poddisruptionbudget-overrides-exporter.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.overridesExporter.enabled (gt (int .Values.overridesExporter.replicas) 1) }} +{{- if kindIs "invalid" .Values.overridesExporter.maxUnavailable }} +{{- fail "`.Values.overridesExporter.maxUnavailable` must be set when `.Values.overridesExporter.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.overridesExporterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.overridesExporterLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.overridesExporterSelectorLabels" . | nindent 6 }} + {{- with .Values.overridesExporter.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/overrides-exporter/service-overrides-exporter-headless.yaml b/charts/mayastor/charts/loki/templates/overrides-exporter/service-overrides-exporter-headless.yaml new file mode 100644 index 0000000..a645a8e --- /dev/null +++ b/charts/mayastor/charts/loki/templates/overrides-exporter/service-overrides-exporter-headless.yaml @@ -0,0 +1,39 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.overridesExporter.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.overridesExporterFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.overridesExporterLabels" . | nindent 4 }} + {{- with .Values.overridesExporter.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.overridesExporter.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + type: ClusterIP + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.overridesExporter.appProtocol.grpc }} + appProtocol: {{ .Values.overridesExporter.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.overridesExporterSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/overrides-exporter/service-overrides-exporter.yaml b/charts/mayastor/charts/loki/templates/overrides-exporter/service-overrides-exporter.yaml new file mode 100644 index 0000000..847aa2f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/overrides-exporter/service-overrides-exporter.yaml @@ -0,0 +1,37 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.overridesExporter.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.overridesExporterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.overridesExporterLabels" . | nindent 4 }} + {{- with .Values.overridesExporter.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.overridesExporter.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.overridesExporter.appProtocol.grpc }} + appProtocol: {{ .Values.overridesExporter.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.overridesExporterSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/pattern-ingester/_helpers-pattern-ingester.tpl b/charts/mayastor/charts/loki/templates/pattern-ingester/_helpers-pattern-ingester.tpl new file mode 100644 index 0000000..5477214 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/pattern-ingester/_helpers-pattern-ingester.tpl @@ -0,0 +1,58 @@ +{{/* +pattern ingester fullname +*/}} +{{- define "loki.patternIngesterFullname" -}} +{{ include "loki.fullname" . }}-pattern-ingester +{{- end }} + +{{/* +pattern ingester common labels +*/}} +{{- define "loki.patternIngesterLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: pattern-ingester +{{- end }} + +{{/* +pattern ingester selector labels +*/}} +{{- define "loki.patternIngesterSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: pattern-ingester +{{- end }} + +{{/* +pattern ingester readinessProbe +*/}} +{{- define "loki.patternIngester.readinessProbe" -}} +{{- with .Values.patternIngester.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- else }} +{{- with .Values.loki.readinessProbe }} +readinessProbe: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +pattern ingester priority class name +*/}} +{{- define "loki.patternIngesterPriorityClassName" }} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.patternIngester.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} + +{{/* +Create the name of the pattern ingester service account +*/}} +{{- define "loki.patternIngesterServiceAccountName" -}} +{{- if .Values.patternIngester.serviceAccount.create -}} + {{ default (print (include "loki.serviceAccountName" .) "-pattern-ingester") .Values.patternIngester.serviceAccount.name }} +{{- else -}} + {{ default (include "loki.serviceAccountName" .) .Values.patternIngester.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/pattern-ingester/statefulset-pattern-ingester.yaml b/charts/mayastor/charts/loki/templates/pattern-ingester/statefulset-pattern-ingester.yaml new file mode 100644 index 0000000..7756b40 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/pattern-ingester/statefulset-pattern-ingester.yaml @@ -0,0 +1,186 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +{{- if (gt (int .Values.patternIngester.replicas) 0) -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.patternIngesterFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.patternIngesterLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.patternIngester.replicas }} + podManagementPolicy: Parallel + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.patternIngesterFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.patternIngester.persistence.enableStatefulSetAutoDeletePVC) }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.patternIngester.persistence.whenDeleted }} + whenScaled: {{ .Values.patternIngester.persistence.whenScaled }} + {{- end }} + selector: + matchLabels: + {{- include "loki.patternIngesterSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.patternIngester.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.patternIngesterLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.patternIngester.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.patternIngester.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.patternIngesterPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.patternIngester.terminationGracePeriodSeconds }} + {{- with .Values.patternIngester.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: pattern-ingester + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.patternIngester.command }} + command: + - {{ coalesce .Values.patternIngester.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=pattern-ingester + {{- with (concat .Values.global.extraArgs .Values.patternIngester.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.patternIngester.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.patternIngester.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + {{- include "loki.patternIngester.readinessProbe" . | nindent 10 }} + volumeMounts: + - name: temp + mountPath: /tmp + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.patternIngester.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.patternIngester.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.patternIngester.extraContainers }} + {{- toYaml .Values.patternIngester.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.patternIngester.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.patternIngester.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.patternIngester.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.patternIngester.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: temp + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- if not .Values.patternIngester.persistence.enabled }} + - name: data + emptyDir: {} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.patternIngester.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.patternIngester.persistence.enabled }} + volumeClaimTemplates: + {{- range .Values.patternIngester.persistence.claims }} + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: {{ .name }} + {{- with .annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .size | quote }} + {{- end }} + {{- end }} +{{- end -}} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/podsecuritypolicy.yaml b/charts/mayastor/charts/loki/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000..05470d9 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/podsecuritypolicy.yaml @@ -0,0 +1,41 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "loki.name" . }} + labels: + {{- include "loki.labels" . | nindent 4 }} +{{- if .Values.rbac.pspAnnotations }} + annotations: +{{ toYaml .Values.rbac.pspAnnotations | indent 4 }} +{{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + volumes: + - 'configMap' + - 'emptyDir' + - 'persistentVolumeClaim' + - 'secret' + - 'projected' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAsNonRoot' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + readOnlyRootFilesystem: true + requiredDropCapabilities: + - ALL +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/provisioner/_helpers.yaml b/charts/mayastor/charts/loki/templates/provisioner/_helpers.yaml new file mode 100644 index 0000000..8b04b07 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/provisioner/_helpers.yaml @@ -0,0 +1,32 @@ +{{/* +provisioner fullname +*/}} +{{- define "enterprise-logs.provisionerFullname" -}} +{{ include "loki.name" . }}-provisioner +{{- end }} + +{{/* +provisioner common labels +*/}} +{{- define "enterprise-logs.provisionerLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: provisioner +{{- end }} + +{{/* +provisioner selector labels +*/}} +{{- define "enterprise-logs.provisionerSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: provisioner +{{- end }} + +{{/* +provisioner image name +*/}} +{{- define "enterprise-logs.provisionerImage" -}} +{{- $dict := dict "service" .Values.enterprise.provisioner.image "global" .Values.global.image "defaultVersion" "latest" -}} +{{- include "loki.baseImage" $dict -}} +{{- end -}} + + diff --git a/charts/mayastor/charts/loki/templates/provisioner/job-provisioner.yaml b/charts/mayastor/charts/loki/templates/provisioner/job-provisioner.yaml new file mode 100644 index 0000000..2609f21 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/provisioner/job-provisioner.yaml @@ -0,0 +1,147 @@ +{{ if and .Values.enterprise.provisioner.enabled .Values.enterprise.enabled }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "enterprise-logs.provisionerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "enterprise-logs.provisionerLabels" . | nindent 4 }} + {{- with .Values.enterprise.provisioner.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.provisioner.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": {{ .Values.enterprise.provisioner.hookType | default "post-install" | quote }} + "helm.sh/hook-weight": "15" +spec: + backoffLimit: 6 + completions: 1 + parallelism: 1 + template: + metadata: + labels: + {{- include "enterprise-logs.provisionerSelectorLabels" . | nindent 8 }} + {{- with .Values.enterprise.provisioner.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.enterprise.provisioner.annotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.enterprise.provisioner.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + securityContext: + {{- toYaml .Values.enterprise.provisioner.securityContext | nindent 8 }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + initContainers: + - name: provisioner + image: {{ template "enterprise-logs.provisionerImage" . }} + imagePullPolicy: {{ .Values.enterprise.provisioner.image.pullPolicy }} + command: + - /bin/sh + - -exuc + - | + {{- range .Values.enterprise.provisioner.additionalTenants }} + /usr/bin/enterprise-logs-provisioner \ + -bootstrap-path=/bootstrap \ + -cluster-name={{ include "loki.clusterName" $ }} \ + -gel-url={{ include "loki.address" $ }} \ + -instance={{ .name }} \ + -access-policy=write-{{ .name }}:{{ .name }}:logs:write \ + -access-policy=read-{{ .name }}:{{ .name }}:logs:read \ + -token=write-{{ .name }} \ + -token=read-{{ .name }} + {{- end -}} + + {{- with .Values.monitoring.selfMonitoring.tenant }} + /usr/bin/enterprise-logs-provisioner \ + -bootstrap-path=/bootstrap \ + -cluster-name={{ include "loki.clusterName" $ }} \ + -gel-url={{ include "loki.address" $ }} \ + -instance={{ .name }} \ + -access-policy=self-monitoring:{{ .name }}:logs:write,logs:read \ + -token=self-monitoring + {{- end }} + volumeMounts: + {{- with .Values.enterprise.provisioner.extraVolumeMounts }} + {{ toYaml . | nindent 12 }} + {{- end }} + - name: bootstrap + mountPath: /bootstrap + - name: admin-token + mountPath: /bootstrap/token + subPath: token + {{- with .Values.enterprise.provisioner.env }} + env: + {{ toYaml . | nindent 12 }} + {{- end }} + containers: + - name: create-secret + image: {{ include "loki.kubectlImage" . }} + imagePullPolicy: {{ .Values.kubectlImage.pullPolicy }} + command: + - /bin/bash + - -exuc + - | + # In case, the admin resources have already been created, the provisioner job + # does not write the token files to the bootstrap mount. + # Therefore, secrets are only created if the respective token files exist. + # Note: the following bash commands should always return a success status code. + # Therefore, in case the token file does not exist, the first clause of the + # or-operation is successful. + {{- range .Values.enterprise.provisioner.additionalTenants }} + ! test -s /bootstrap/token-write-{{ .name }} || \ + kubectl --namespace "{{ .secretNamespace }}" create secret generic "{{ include "enterprise-logs.provisionedSecretPrefix" $ }}-{{ .name }}" \ + --from-literal=token-write="$(cat /bootstrap/token-write-{{ .name }})" \ + --from-literal=token-read="$(cat /bootstrap/token-read-{{ .name }})" + {{- end }} + {{- $namespace := $.Release.Namespace }} + {{- with .Values.monitoring.selfMonitoring.tenant }} + {{- $secretNamespace := tpl .secretNamespace $ }} + ! test -s /bootstrap/token-self-monitoring || \ + kubectl --namespace "{{ $namespace }}" create secret generic "{{ include "enterprise-logs.selfMonitoringTenantSecret" $ }}" \ + --from-literal=username="{{ .name }}" \ + --from-literal=password="$(cat /bootstrap/token-self-monitoring)" + {{- if not (eq $secretNamespace $namespace) }} + ! test -s /bootstrap/token-self-monitoring || \ + kubectl --namespace "{{ $secretNamespace }}" create secret generic "{{ include "enterprise-logs.selfMonitoringTenantSecret" $ }}" \ + --from-literal=username="{{ .name }}" \ + --from-literal=password="$(cat /bootstrap/token-self-monitoring)" + {{- end }} + {{- end }} + volumeMounts: + {{- with .Values.enterprise.provisioner.extraVolumeMounts }} + {{ toYaml . | nindent 12 }} + {{- end }} + - name: bootstrap + mountPath: /bootstrap + {{- with .Values.enterprise.provisioner.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.enterprise.provisioner.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.enterprise.provisioner.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + restartPolicy: OnFailure + serviceAccount: {{ include "enterprise-logs.provisionerFullname" . }} + serviceAccountName: {{ include "enterprise-logs.provisionerFullname" . }} + volumes: + - name: admin-token + secret: + secretName: "{{ include "enterprise-logs.adminTokenSecret" . }}" + - name: bootstrap + emptyDir: {} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/provisioner/role-provisioner.yaml b/charts/mayastor/charts/loki/templates/provisioner/role-provisioner.yaml new file mode 100644 index 0000000..4c8121f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/provisioner/role-provisioner.yaml @@ -0,0 +1,21 @@ +{{ if and .Values.enterprise.provisioner.enabled .Values.enterprise.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ if not .Values.rbac.namespaced }}Cluster{{ end }}Role +metadata: + name: {{ template "enterprise-logs.provisionerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "enterprise-logs.provisionerLabels" . | nindent 4 }} + {{- with .Values.enterprise.provisioner.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.provisioner.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["create"] +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/provisioner/rolebinding-provisioner.yaml b/charts/mayastor/charts/loki/templates/provisioner/rolebinding-provisioner.yaml new file mode 100644 index 0000000..5cd4560 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/provisioner/rolebinding-provisioner.yaml @@ -0,0 +1,26 @@ +{{ if and .Values.enterprise.provisioner.enabled .Values.enterprise.enabled}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ if not .Values.rbac.namespaced }}Cluster{{ else }}Role{{ end }}Binding +metadata: + name: {{ template "enterprise-logs.provisionerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "enterprise-logs.provisionerLabels" . | nindent 4 }} + {{- with .Values.enterprise.provisioner.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.provisioner.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: {{ if not .Values.rbac.namespaced }}Cluster{{ end }}Role + name: {{ template "enterprise-logs.provisionerFullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "enterprise-logs.provisionerFullname" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/provisioner/serviceaccount-provisioner.yaml b/charts/mayastor/charts/loki/templates/provisioner/serviceaccount-provisioner.yaml new file mode 100644 index 0000000..81e92e9 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/provisioner/serviceaccount-provisioner.yaml @@ -0,0 +1,18 @@ +{{ if and .Values.enterprise.provisioner.enabled .Values.enterprise.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "enterprise-logs.provisionerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "enterprise-logs.provisionerLabels" . | nindent 4 }} + {{- with .Values.enterprise.provisioner.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.provisioner.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/querier/_helpers-querier.tpl b/charts/mayastor/charts/loki/templates/querier/_helpers-querier.tpl new file mode 100644 index 0000000..aa557c5 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/querier/_helpers-querier.tpl @@ -0,0 +1,32 @@ +{{/* +querier fullname +*/}} +{{- define "loki.querierFullname" -}} +{{ include "loki.fullname" . }}-querier +{{- end }} + +{{/* +querier common labels +*/}} +{{- define "loki.querierLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: querier +{{- end }} + +{{/* +querier selector labels +*/}} +{{- define "loki.querierSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: querier +{{- end }} + +{{/* +querier priority class name +*/}} +{{- define "loki.querierPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.querier.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/querier/deployment-querier.yaml b/charts/mayastor/charts/loki/templates/querier/deployment-querier.yaml new file mode 100644 index 0000000..ffebc85 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/querier/deployment-querier.yaml @@ -0,0 +1,163 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.querierFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querierLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.querier.autoscaling.enabled }} + replicas: {{ .Values.querier.replicas }} +{{- end }} + strategy: + rollingUpdate: + maxSurge: {{ .Values.querier.maxSurge }} + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.querierSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.querier.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.querierLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.querier.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.querier.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.querier.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.querierPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.querier.terminationGracePeriodSeconds }} + {{- with .Values.querier.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: querier + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=querier + {{- if .Values.ingester.zoneAwareReplication.enabled }} + {{- if and (.Values.ingester.zoneAwareReplication.migration.enabled) (not .Values.ingester.zoneAwareReplication.migration.readPath) }} + - -distributor.zone-awareness-enabled=false + {{- else }} + - -distributor.zone-awareness-enabled=true + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraArgs .Values.querier.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.querier.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.querier.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + livenessProbe: + {{- toYaml .Values.loki.livenessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.querier.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.querier.resources | nindent 12 }} + {{- if .Values.querier.extraContainers }} + {{- toYaml .Values.querier.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.querier.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.querier.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.querier.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.querier.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + - name: data + emptyDir: {} + {{- with (concat .Values.global.extraVolumes .Values.querier.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/querier/hpa.yaml b/charts/mayastor/charts/loki/templates/querier/hpa.yaml new file mode 100644 index 0000000..08d81cb --- /dev/null +++ b/charts/mayastor/charts/loki/templates/querier/hpa.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.querier.autoscaling.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.querierFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querierLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "loki.querierFullname" . }} + minReplicas: {{ .Values.querier.autoscaling.minReplicas }} + maxReplicas: {{ .Values.querier.autoscaling.maxReplicas }} + metrics: + {{- with .Values.querier.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.querier.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.querier.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.querier.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.querier.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.querier.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/querier/poddisruptionbudget-querier.yaml b/charts/mayastor/charts/loki/templates/querier/poddisruptionbudget-querier.yaml new file mode 100644 index 0000000..9dff3cd --- /dev/null +++ b/charts/mayastor/charts/loki/templates/querier/poddisruptionbudget-querier.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.querier.replicas) 1) }} +{{- if kindIs "invalid" .Values.querier.maxUnavailable }} +{{- fail "`.Values.querier.maxUnavailable` must be set when `.Values.querier.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.querierFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querierLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.querierSelectorLabels" . | nindent 6 }} + {{- with .Values.querier.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/querier/service-querier.yaml b/charts/mayastor/charts/loki/templates/querier/service-querier.yaml new file mode 100644 index 0000000..15c9c6a --- /dev/null +++ b/charts/mayastor/charts/loki/templates/querier/service-querier.yaml @@ -0,0 +1,36 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.querierFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querierLabels" . | nindent 4 }} + {{- with .Values.querier.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.querier.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.querier.appProtocol.grpc }} + appProtocol: {{ .Values.querier.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.querierSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/query-frontend/_helpers-query-frontend.tpl b/charts/mayastor/charts/loki/templates/query-frontend/_helpers-query-frontend.tpl new file mode 100644 index 0000000..5aebde7 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/query-frontend/_helpers-query-frontend.tpl @@ -0,0 +1,32 @@ +{{/* +query-frontend fullname +*/}} +{{- define "loki.queryFrontendFullname" -}} +{{ include "loki.fullname" . }}-query-frontend +{{- end }} + +{{/* +query-frontend common labels +*/}} +{{- define "loki.queryFrontendLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: query-frontend +{{- end }} + +{{/* +query-frontend selector labels +*/}} +{{- define "loki.queryFrontendSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: query-frontend +{{- end }} + +{{/* +query-frontend priority class name +*/}} +{{- define "loki.queryFrontendPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.queryFrontend.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/query-frontend/deployment-query-frontend.yaml b/charts/mayastor/charts/loki/templates/query-frontend/deployment-query-frontend.yaml new file mode 100644 index 0000000..1476d67 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/query-frontend/deployment-query-frontend.yaml @@ -0,0 +1,145 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.queryFrontendFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.queryFrontendLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.queryFrontend.autoscaling.enabled }} + replicas: {{ .Values.queryFrontend.replicas }} +{{- end }} + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.queryFrontendSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryFrontend.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.queryFrontendLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.queryFrontend.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.queryFrontend.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryFrontend.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.queryFrontendPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.queryFrontend.terminationGracePeriodSeconds }} + containers: + - name: query-frontend + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + {{- if or .Values.loki.command .Values.queryFrontend.command }} + command: + - {{ coalesce .Values.queryFrontend.command .Values.loki.command | quote }} + {{- end }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=query-frontend + {{- with (concat .Values.global.extraArgs .Values.queryFrontend.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.queryFrontend.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.queryFrontend.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.queryFrontend.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.queryFrontend.resources | nindent 12 }} + {{- if .Values.queryFrontend.extraContainers }} + {{- toYaml .Values.queryFrontend.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.queryFrontend.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryFrontend.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryFrontend.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.queryFrontend.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/query-frontend/hpa.yaml b/charts/mayastor/charts/loki/templates/query-frontend/hpa.yaml new file mode 100644 index 0000000..c326287 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/query-frontend/hpa.yaml @@ -0,0 +1,55 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.queryFrontend.autoscaling.enabled }} +{{- $apiVersion := include "loki.hpa.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.queryFrontendFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.queryFrontendLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "loki.queryFrontendFullname" . }} + minReplicas: {{ .Values.queryFrontend.autoscaling.minReplicas }} + maxReplicas: {{ .Values.queryFrontend.autoscaling.maxReplicas }} + metrics: + {{- with .Values.queryFrontend.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.queryFrontend.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if (eq $apiVersion "autoscaling/v2") }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.queryFrontend.autoscaling.customMetrics }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.queryFrontend.autoscaling.behavior.enabled }} + behavior: + {{- with .Values.queryFrontend.autoscaling.behavior.scaleDown }} + scaleDown: {{ toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.queryFrontend.autoscaling.behavior.scaleUp }} + scaleUp: {{ toYaml . | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/query-frontend/poddisruptionbudget-query-frontend.yaml b/charts/mayastor/charts/loki/templates/query-frontend/poddisruptionbudget-query-frontend.yaml new file mode 100644 index 0000000..f100405 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/query-frontend/poddisruptionbudget-query-frontend.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.queryFrontend.replicas) 1) }} +{{- if kindIs "invalid" .Values.queryFrontend.maxUnavailable }} +{{- fail "`.Values.queryFrontend.maxUnavailable` must be set when `.Values.queryFrontend.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.queryFrontendFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.queryFrontendLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.queryFrontendSelectorLabels" . | nindent 6 }} + {{- with .Values.queryFrontend.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/query-frontend/service-query-frontend-headless.yaml b/charts/mayastor/charts/loki/templates/query-frontend/service-query-frontend-headless.yaml new file mode 100644 index 0000000..8da9054 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/query-frontend/service-query-frontend-headless.yaml @@ -0,0 +1,46 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.queryFrontendFullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.queryFrontendLabels" . | nindent 4 }} + {{- with .Values.queryFrontend.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.queryFrontend.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + type: ClusterIP + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.queryFrontend.appProtocol.grpc }} + appProtocol: {{ .Values.queryFrontend.appProtocol.grpc }} + {{- end }} + - name: grpclb + port: 9096 + targetPort: grpc + protocol: TCP + {{- if .Values.queryFrontend.appProtocol.grpc }} + appProtocol: {{ .Values.queryFrontend.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.queryFrontendSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/query-frontend/service-query-frontend.yaml b/charts/mayastor/charts/loki/templates/query-frontend/service-query-frontend.yaml new file mode 100644 index 0000000..a239695 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/query-frontend/service-query-frontend.yaml @@ -0,0 +1,44 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.queryFrontendFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.queryFrontendLabels" . | nindent 4 }} + {{- with .Values.queryFrontend.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.queryFrontend.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- if .Values.queryFrontend.appProtocol.grpc }} + appProtocol: {{ .Values.queryFrontend.appProtocol.grpc }} + {{- end }} + - name: grpclb + port: 9096 + targetPort: grpc + protocol: TCP + {{- if .Values.queryFrontend.appProtocol.grpc }} + appProtocol: {{ .Values.queryFrontend.appProtocol.grpc }} + {{- end }} + selector: + {{- include "loki.queryFrontendSelectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/query-scheduler/_helpers-query-scheduler.tpl b/charts/mayastor/charts/loki/templates/query-scheduler/_helpers-query-scheduler.tpl new file mode 100644 index 0000000..1f64802 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/query-scheduler/_helpers-query-scheduler.tpl @@ -0,0 +1,40 @@ +{{/* +query-scheduler fullname +*/}} +{{- define "loki.querySchedulerFullname" -}} +{{ include "loki.fullname" . }}-query-scheduler +{{- end }} + +{{/* +query-scheduler common labels +*/}} +{{- define "loki.querySchedulerLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: query-scheduler +{{- end }} + +{{/* +query-scheduler selector labels +*/}} +{{- define "loki.querySchedulerSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: query-scheduler +{{- end }} + +{{/* +query-scheduler image +*/}} +{{- define "loki.querySchedulerImage" -}} +{{- $dict := dict "loki" .Values.loki.image "service" .Values.queryScheduler.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}} +{{- include "loki.lokiImage" $dict -}} +{{- end }} + +{{/* +query-scheduler priority class name +*/}} +{{- define "loki.querySchedulerPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.queryScheduler.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/query-scheduler/deployment-query-scheduler.yaml b/charts/mayastor/charts/loki/templates/query-scheduler/deployment-query-scheduler.yaml new file mode 100644 index 0000000..28dadaa --- /dev/null +++ b/charts/mayastor/charts/loki/templates/query-scheduler/deployment-query-scheduler.yaml @@ -0,0 +1,143 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.querySchedulerFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querySchedulerLabels" . | nindent 4 }} + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.queryScheduler.replicas }} + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.querySchedulerSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryScheduler.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.querySchedulerLabels" . | nindent 8 }} + {{- with merge (dict) .Values.loki.podLabels .Values.queryScheduler.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + app.kubernetes.io/part-of: memberlist + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.queryScheduler.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryScheduler.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.querySchedulerPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.queryScheduler.terminationGracePeriodSeconds }} + containers: + - name: query-scheduler + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=query-scheduler + {{- with (concat .Values.global.extraArgs .Values.queryScheduler.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.queryScheduler.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.queryScheduler.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + livenessProbe: + {{- toYaml .Values.loki.livenessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.queryScheduler.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.queryScheduler.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.queryScheduler.extraContainers }} + {{- toYaml .Values.queryScheduler.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.queryScheduler.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryScheduler.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.queryScheduler.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.queryScheduler.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/query-scheduler/poddisruptionbudget-query-scheduler.yaml b/charts/mayastor/charts/loki/templates/query-scheduler/poddisruptionbudget-query-scheduler.yaml new file mode 100644 index 0000000..ed8051f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/query-scheduler/poddisruptionbudget-query-scheduler.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.queryScheduler.replicas) 1) }} +{{- if kindIs "invalid" .Values.queryScheduler.maxUnavailable }} +{{- fail "`.Values.queryScheduler.maxUnavailable` must be set when `.Values.queryScheduler.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.querySchedulerFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querySchedulerLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.querySchedulerSelectorLabels" . | nindent 6 }} + {{- with .Values.queryScheduler.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/query-scheduler/service-query-scheduler.yaml b/charts/mayastor/charts/loki/templates/query-scheduler/service-query-scheduler.yaml new file mode 100644 index 0000000..746c7bd --- /dev/null +++ b/charts/mayastor/charts/loki/templates/query-scheduler/service-query-scheduler.yaml @@ -0,0 +1,38 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.querySchedulerFullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.querySchedulerLabels" . | nindent 4 }} + {{- with .Values.queryScheduler.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.queryScheduler.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + publishNotReadyAddresses: true + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpclb + port: 9095 + targetPort: grpc + protocol: TCP + {{- with .Values.queryScheduler.appProtocol.grpc }} + appProtocol: {{ . }} + {{- end }} + selector: + {{- include "loki.querySchedulerSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/read/_helpers-read.tpl b/charts/mayastor/charts/loki/templates/read/_helpers-read.tpl new file mode 100644 index 0000000..d205314 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/read/_helpers-read.tpl @@ -0,0 +1,32 @@ +{{/* +read fullname +*/}} +{{- define "loki.readFullname" -}} +{{ include "loki.name" . }}-read +{{- end }} + +{{/* +read common labels +*/}} +{{- define "loki.readLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: read +{{- end }} + +{{/* +read selector labels +*/}} +{{- define "loki.readSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: read +{{- end }} + +{{/* +read priority class name +*/}} +{{- define "loki.readPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.read.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/read/deployment-read.yaml b/charts/mayastor/charts/loki/templates/read/deployment-read.yaml new file mode 100644 index 0000000..f024a40 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/read/deployment-read.yaml @@ -0,0 +1,163 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.readFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + app.kubernetes.io/part-of: memberlist + {{- include "loki.readLabels" . | nindent 4 }} + {{- if or (not (empty .Values.loki.annotations)) (not (empty .Values.backend.annotations))}} + annotations: + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.read.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + {{- if not .Values.read.autoscaling.enabled }} + replicas: {{ .Values.read.replicas }} + {{- end }} + strategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.readSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + app.kubernetes.io/part-of: memberlist + {{- include "loki.readSelectorLabels" . | nindent 8 }} + {{- with .Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.selectorLabels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.readPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.read.terminationGracePeriodSeconds }} + containers: + - name: loki + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target={{ .Values.read.targetModule }} + - -legacy-read-mode=false + - -common.compactor-grpc-address={{ include "loki.backendFullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}:{{ .Values.loki.server.grpc_listen_port }} + {{- with .Values.read.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.loki.server.http_listen_port }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.loki.server.grpc_listen_port }} + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with .Values.read.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.read.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: tmp + mountPath: /tmp + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end}} + {{- with .Values.read.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.read.resources | nindent 12 }} + {{- with .Values.read.extraContainers }} + {{- toYaml . | nindent 8}} + {{- end }} + {{- with .Values.read.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.read.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: tmp + emptyDir: {} + - name: data + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with .Values.read.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/read/hpa.yaml b/charts/mayastor/charts/loki/templates/read/hpa.yaml new file mode 100644 index 0000000..5515ecb --- /dev/null +++ b/charts/mayastor/charts/loki/templates/read/hpa.yaml @@ -0,0 +1,55 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- $autoscalingv2 := .Capabilities.APIVersions.Has "autoscaling/v2" -}} +{{- if and $isSimpleScalable ( .Values.read.autoscaling.enabled ) }} +{{- if $autoscalingv2 }} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta1 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.readFullname" . }} + labels: + {{- include "loki.readLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 +{{- if and $isSimpleScalable (not .Values.read.legacyReadTarget ) }} + kind: Deployment + name: {{ include "loki.readFullname" . }} +{{- else }} + kind: StatefulSet + name: {{ include "loki.readFullname" . }} +{{- end }} + minReplicas: {{ .Values.read.autoscaling.minReplicas }} + maxReplicas: {{ .Values.read.autoscaling.maxReplicas }} + {{- with .Values.read.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} + metrics: + {{- with .Values.read.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.read.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/read/poddisruptionbudget-read.yaml b/charts/mayastor/charts/loki/templates/read/poddisruptionbudget-read.yaml new file mode 100644 index 0000000..af4fcbf --- /dev/null +++ b/charts/mayastor/charts/loki/templates/read/poddisruptionbudget-read.yaml @@ -0,0 +1,15 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (gt (int .Values.read.replicas) 1) }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.readFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.readLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.readSelectorLabels" . | nindent 6 }} + maxUnavailable: 1 +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/read/service-read-headless.yaml b/charts/mayastor/charts/loki/templates/read/service-read-headless.yaml new file mode 100644 index 0000000..14ba0f6 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/read/service-read-headless.yaml @@ -0,0 +1,41 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{ if $isSimpleScalable }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.readFullname" . }}-headless + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.readSelectorLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.read.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + variant: headless + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.read.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + appProtocol: tcp + selector: + {{- include "loki.readSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/read/service-read.yaml b/charts/mayastor/charts/loki/templates/read/service-read.yaml new file mode 100644 index 0000000..f4000fd --- /dev/null +++ b/charts/mayastor/charts/loki/templates/read/service-read.yaml @@ -0,0 +1,37 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isSimpleScalable }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.readFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.readLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.read.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.read.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + selector: + {{- include "loki.readSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/read/statefulset-read.yaml b/charts/mayastor/charts/loki/templates/read/statefulset-read.yaml new file mode 100644 index 0000000..e58ac6d --- /dev/null +++ b/charts/mayastor/charts/loki/templates/read/statefulset-read.yaml @@ -0,0 +1,194 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (.Values.read.legacyReadTarget ) }} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.readFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + app.kubernetes.io/part-of: memberlist + {{- include "loki.readLabels" . | nindent 4 }} + {{- if or (not (empty .Values.loki.annotations)) (not (empty .Values.read.annotations))}} + annotations: + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.read.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: +{{- if not .Values.read.autoscaling.enabled }} + {{- if eq .Values.deploymentMode "SingleBinary" }} + replicas: 0 + {{- else }} + replicas: {{ .Values.read.replicas }} + {{- end }} +{{- end }} + podManagementPolicy: {{ .Values.read.podManagementPolicy }} + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ printf "%s-headless" (include "loki.readFullname" .) }} + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.read.persistence.enableStatefulSetAutoDeletePVC) }} + {{/* + Data on the read nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete + {{- end }} + selector: + matchLabels: + {{- include "loki.readSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + app.kubernetes.io/part-of: memberlist + {{- include "loki.readLabels" . | nindent 8 }} + {{- with merge (dict) .Values.loki.podLabels .Values.read.podLabels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{ include "loki.enableServiceLinks" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.readPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.read.terminationGracePeriodSeconds }} + containers: + - name: loki + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target={{ .Values.read.targetModule }} + {{- with (concat .Values.global.extraArgs .Values.read.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.loki.server.http_listen_port }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.loki.server.grpc_listen_port }} + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.read.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.read.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + {{- with .Values.read.lifecycle }} + lifecycle: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: tmp + mountPath: /tmp + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end}} + {{- with (concat .Values.global.extraVolumeMounts .Values.read.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.read.resources | nindent 12 }} + {{- with .Values.read.extraContainers }} + {{- toYaml . | nindent 8}} + {{- end }} + {{- with .Values.read.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.read.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.read.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: tmp + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.read.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + {{- with .Values.read.persistence.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.read.persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .Values.read.persistence.size | quote }} + {{- with .Values.read.persistence.selector }} + selector: + {{- toYaml . | nindent 10 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/results-cache/poddisruptionbudget-results-cache.yaml b/charts/mayastor/charts/loki/templates/results-cache/poddisruptionbudget-results-cache.yaml new file mode 100644 index 0000000..6bc393a --- /dev/null +++ b/charts/mayastor/charts/loki/templates/results-cache/poddisruptionbudget-results-cache.yaml @@ -0,0 +1,16 @@ +{{- if .Values.resultsCache.enabled }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.fullname" . }}-memcached-results-cache + namespace: {{ .Release.Namespace }} + labels: + {{- include "loki.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: memcached-results-cache +spec: + selector: + matchLabels: + {{- include "loki.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: memcached-results-cache + maxUnavailable: 1 +{{- end -}} diff --git a/charts/mayastor/charts/loki/templates/results-cache/service-results-cache-headless.yaml b/charts/mayastor/charts/loki/templates/results-cache/service-results-cache-headless.yaml new file mode 100644 index 0000000..ce92008 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/results-cache/service-results-cache-headless.yaml @@ -0,0 +1 @@ +{{- include "loki.memcached.service" (dict "ctx" $ "valuesSection" "resultsCache" "component" "results-cache" ) }} diff --git a/charts/mayastor/charts/loki/templates/results-cache/statefulset-results-cache.yaml b/charts/mayastor/charts/loki/templates/results-cache/statefulset-results-cache.yaml new file mode 100644 index 0000000..042e74e --- /dev/null +++ b/charts/mayastor/charts/loki/templates/results-cache/statefulset-results-cache.yaml @@ -0,0 +1 @@ +{{- include "loki.memcached.statefulSet" (dict "ctx" $ "valuesSection" "resultsCache" "component" "results-cache" ) }} diff --git a/charts/mayastor/charts/loki/templates/role.yaml b/charts/mayastor/charts/loki/templates/role.yaml new file mode 100644 index 0000000..1e714b6 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/role.yaml @@ -0,0 +1,36 @@ +{{- if or .Values.rbac.pspEnabled .Values.rbac.sccEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "loki.name" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +{{- if .Values.rbac.pspEnabled }} +rules: + - apiGroups: + - policy + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ include "loki.name" . }} +{{- end }} +{{- if .Values.rbac.sccEnabled }} +rules: + - apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + verbs: + - use + resourceNames: + - {{ include "loki.name" . }} + {{- if and .Values.rbac.namespaced .Values.sidecar.rules.enabled }} + - apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/rolebinding.yaml b/charts/mayastor/charts/loki/templates/rolebinding.yaml new file mode 100644 index 0000000..cc0dfd2 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if or .Values.rbac.pspEnabled .Values.rbac.sccEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "loki.name" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "loki.name" . }} +subjects: + - kind: ServiceAccount + name: {{ include "loki.serviceAccountName" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ruler/_helpers-ruler.tpl b/charts/mayastor/charts/loki/templates/ruler/_helpers-ruler.tpl new file mode 100644 index 0000000..2079e03 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ruler/_helpers-ruler.tpl @@ -0,0 +1,47 @@ +{{/* +ruler fullname +*/}} +{{- define "loki.rulerFullname" -}} +{{ include "loki.fullname" . }}-ruler +{{- end }} + +{{/* +ruler common labels +*/}} +{{- define "loki.rulerLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: ruler +{{- end }} + +{{/* +ruler selector labels +*/}} +{{- define "loki.rulerSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: ruler +{{- end }} + +{{/* +ruler image +*/}} +{{- define "loki.rulerImage" -}} +{{- $dict := dict "loki" .Values.loki.image "service" .Values.ruler.image "global" .Values.global.image "defaultVersion" .Chart.AppVersion -}} +{{- include "loki.lokiImage" $dict -}} +{{- end }} + +{{/* +format rules dir +*/}} +{{- define "loki.rulerRulesDirName" -}} +rules-{{ . | replace "_" "-" | trimSuffix "-" | lower }} +{{- end }} + +{{/* +ruler priority class name +*/}} +{{- define "loki.rulerPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.ruler.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ruler/configmap-ruler.yaml b/charts/mayastor/charts/loki/templates/ruler/configmap-ruler.yaml new file mode 100644 index 0000000..3a0c533 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ruler/configmap-ruler.yaml @@ -0,0 +1,15 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if $isDistributed }} +{{- range $dir, $files := .Values.ruler.directories }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "loki.rulerFullname" $ }}-{{ include "loki.rulerRulesDirName" $dir }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.rulerLabels" $ | nindent 4 }} +data: + {{- toYaml $files | nindent 2}} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ruler/poddisruptionbudget-ruler.yaml b/charts/mayastor/charts/loki/templates/ruler/poddisruptionbudget-ruler.yaml new file mode 100644 index 0000000..b9c03cf --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ruler/poddisruptionbudget-ruler.yaml @@ -0,0 +1,21 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed (gt (int .Values.ruler.replicas) 1) }} +{{- if kindIs "invalid" .Values.ruler.maxUnavailable }} +{{- fail "`.Values.ruler.maxUnavailable` must be set when `.Values.ruler.replicas` is greater than 1." }} +{{- else }} +apiVersion: {{ include "loki.pdb.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.rulerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.rulerLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.rulerSelectorLabels" . | nindent 6 }} + {{- with .Values.ruler.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ruler/service-ruler.yaml b/charts/mayastor/charts/loki/templates/ruler/service-ruler.yaml new file mode 100644 index 0000000..8847683 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ruler/service-ruler.yaml @@ -0,0 +1,37 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ruler.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.rulerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.rulerSelectorLabels" . | nindent 4 }} + {{- with .Values.ruler.serviceLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.ruler.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: 3100 + targetPort: http-metrics + protocol: TCP + - name: grpc + port: 9095 + targetPort: grpc + protocol: TCP + {{- with .Values.ruler.appProtocol.grpc }} + appProtocol: {{ . }} + {{- end }} + selector: + {{- include "loki.rulerSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/ruler/statefulset-ruler.yaml b/charts/mayastor/charts/loki/templates/ruler/statefulset-ruler.yaml new file mode 100644 index 0000000..20b53a4 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/ruler/statefulset-ruler.yaml @@ -0,0 +1,183 @@ +{{- $isDistributed := eq (include "loki.deployment.isDistributed" .) "true" -}} +{{- if and $isDistributed .Values.ruler.enabled }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.rulerFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.rulerLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- with .Values.loki.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.ruler.replicas }} + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + serviceName: {{ include "loki.rulerFullname" . }} + selector: + matchLabels: + {{- include "loki.rulerSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "loki.config.checksum" . | nindent 8 }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ruler.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.rulerLabels" . | nindent 8 }} + app.kubernetes.io/part-of: memberlist + {{- with merge (dict) .Values.loki.podLabels .Values.ruler.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.Version }} + {{- with .Values.ruler.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ruler.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.rulerPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.ruler.terminationGracePeriodSeconds }} + {{- with .Values.ruler.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: ruler + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=ruler + {{- with (concat .Values.global.extraArgs .Values.ruler.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: 3100 + protocol: TCP + - name: grpc + containerPort: 9095 + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.ruler.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.ruler.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + - name: tmp + mountPath: /tmp/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- range $dir, $_ := .Values.ruler.directories }} + - name: {{ include "loki.rulerRulesDirName" $dir }} + mountPath: /etc/loki/rules/{{ $dir }} + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.ruler.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.ruler.resources | nindent 12 }} + {{- with .Values.ruler.extraContainers }} + {{- toYaml . | nindent 8}} + {{- end }} + {{- with .Values.ruler.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ruler.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ruler.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.ruler.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- range $dir, $_ := .Values.ruler.directories }} + - name: {{ include "loki.rulerRulesDirName" $dir }} + configMap: + name: {{ include "loki.rulerFullname" $ }}-{{ include "loki.rulerRulesDirName" $dir }} + {{- end }} + - name: tmp + emptyDir: {} + {{- with (concat .Values.global.extraVolumes .Values.ruler.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if not .Values.ruler.persistence.enabled }} + - name: data + emptyDir: {} + {{- else }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + {{- with .Values.ruler.persistence.annotations }} + annotations: + {{- . | toYaml | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.ruler.persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .Values.ruler.persistence.size | quote }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/runtime-configmap.yaml b/charts/mayastor/charts/loki/templates/runtime-configmap.yaml new file mode 100644 index 0000000..2f38193 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/runtime-configmap.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "loki.name" . }}-runtime + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +data: + runtime-config.yaml: | + {{- tpl (toYaml .Values.loki.runtimeConfig) . | nindent 4 }} diff --git a/charts/mayastor/charts/loki/templates/secret-license.yaml b/charts/mayastor/charts/loki/templates/secret-license.yaml new file mode 100644 index 0000000..eaa519f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/secret-license.yaml @@ -0,0 +1,11 @@ +{{- if and (not .Values.enterprise.useExternalLicense) .Values.enterprise.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: enterprise-logs-license + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +data: + license.jwt: {{ .Values.enterprise.license.contents | b64enc }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/securitycontextconstraints.yaml b/charts/mayastor/charts/loki/templates/securitycontextconstraints.yaml new file mode 100644 index 0000000..c3a604d --- /dev/null +++ b/charts/mayastor/charts/loki/templates/securitycontextconstraints.yaml @@ -0,0 +1,40 @@ +{{- if .Values.rbac.sccEnabled }} +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: {{ include "loki.name" . }} + labels: + {{- include "loki.labels" . | nindent 4 }} +allowHostDirVolumePlugin: false +allowHostIPC: false +allowHostNetwork: false +allowHostPID: false +allowHostPorts: false +allowPrivilegeEscalation: true +allowPrivilegedContainer: false +allowedCapabilities: [] +defaultAddCapabilities: null +fsGroup: + type: RunAsAny +groups: [] +priority: null +readOnlyRootFilesystem: false +requiredDropCapabilities: + - ALL +runAsUser: + type: RunAsAny +seLinuxContext: + type: MustRunAs +seccompProfiles: + - '*' +supplementalGroups: + type: RunAsAny +volumes: + - configMap + - downwardAPI + - emptyDir + - hostPath + - persistentVolumeClaim + - projected + - secret +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/service-memberlist.yaml b/charts/mayastor/charts/loki/templates/service-memberlist.yaml new file mode 100644 index 0000000..3d46f23 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/service-memberlist.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.memberlist" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.memberlist.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: tcp + port: 7946 + targetPort: http-memberlist + protocol: TCP + {{- with .Values.memberlist.service.publishNotReadyAddresses }} + publishNotReadyAddresses: {{ . }} + {{- end }} + selector: + {{- include "loki.selectorLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist diff --git a/charts/mayastor/charts/loki/templates/serviceaccount.yaml b/charts/mayastor/charts/loki/templates/serviceaccount.yaml new file mode 100644 index 0000000..dd89141 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/serviceaccount.yaml @@ -0,0 +1,21 @@ +{{ if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "loki.serviceAccountName" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- tpl (toYaml . | nindent 4) $ }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- with .Values.serviceAccount.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/single-binary/_helpers-single-binary.tpl b/charts/mayastor/charts/loki/templates/single-binary/_helpers-single-binary.tpl new file mode 100644 index 0000000..4ea3c6d --- /dev/null +++ b/charts/mayastor/charts/loki/templates/single-binary/_helpers-single-binary.tpl @@ -0,0 +1,34 @@ +{{/* +singleBinary common labels +*/}} +{{- define "loki.singleBinaryLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: single-binary +{{- end }} + + +{{/* singleBinary selector labels */}} +{{- define "loki.singleBinarySelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: single-binary +{{- end }} + +{{/* +singleBinary priority class name +*/}} +{{- define "loki.singleBinaryPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.singleBinary.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} + +{{/* singleBinary replicas calculation */}} +{{- define "loki.singleBinaryReplicas" -}} +{{- $replicas := 1 }} +{{- $usingObjectStorage := eq (include "loki.isUsingObjectStorage" .) "true" }} +{{- if and $usingObjectStorage (gt (int .Values.singleBinary.replicas) 1)}} +{{- $replicas = int .Values.singleBinary.replicas -}} +{{- end }} +{{- printf "%d" $replicas }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/single-binary/hpa.yaml b/charts/mayastor/charts/loki/templates/single-binary/hpa.yaml new file mode 100644 index 0000000..c529f18 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/single-binary/hpa.yaml @@ -0,0 +1,51 @@ +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- $usingObjectStorage := eq (include "loki.isUsingObjectStorage" .) "true" }} +{{- $autoscalingv2 := .Capabilities.APIVersions.Has "autoscaling/v2" -}} +{{- if and $isSingleBinary $usingObjectStorage ( .Values.singleBinary.autoscaling.enabled ) }} +{{- if $autoscalingv2 }} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta1 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.singleBinaryFullname" . }} + labels: + {{- include "loki.singleBinaryLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.singleBinaryFullname" . }} + minReplicas: {{ .Values.singleBinary.autoscaling.minReplicas }} + maxReplicas: {{ .Values.singleBinary.autoscaling.maxReplicas }} + {{- with .Values.singleBinary.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} + metrics: + {{- with .Values.singleBinary.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.singleBinary.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/single-binary/pdb.yaml b/charts/mayastor/charts/loki/templates/single-binary/pdb.yaml new file mode 100644 index 0000000..bb1e1cc --- /dev/null +++ b/charts/mayastor/charts/loki/templates/single-binary/pdb.yaml @@ -0,0 +1,16 @@ +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- if and .Values.podDisruptionBudget $isSingleBinary -}} +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.singleBinarySelectorLabels" . | nindent 6 }} +{{ toYaml .Values.podDisruptionBudget | indent 2 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/single-binary/service-headless.yaml b/charts/mayastor/charts/loki/templates/single-binary/service-headless.yaml new file mode 100644 index 0000000..7522240 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/single-binary/service-headless.yaml @@ -0,0 +1,35 @@ +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- if $isSingleBinary }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.name" . }}-headless + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.singleBinary.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + variant: headless + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.singleBinary.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + clusterIP: None + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + selector: + {{- include "loki.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/single-binary/service.yaml b/charts/mayastor/charts/loki/templates/single-binary/service.yaml new file mode 100644 index 0000000..352fcad --- /dev/null +++ b/charts/mayastor/charts/loki/templates/single-binary/service.yaml @@ -0,0 +1,40 @@ +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- if $isSingleBinary }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.singleBinaryFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.labels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.singleBinary.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.singleBinary.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + selector: + {{- include "loki.singleBinarySelectorLabels" . | nindent 4 }} + {{- with .Values.singleBinary.selectorLabels }} + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/single-binary/statefulset.yaml b/charts/mayastor/charts/loki/templates/single-binary/statefulset.yaml new file mode 100644 index 0000000..54f3d92 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/single-binary/statefulset.yaml @@ -0,0 +1,278 @@ +{{- $isSingleBinary := eq (include "loki.deployment.isSingleBinary" .) "true" -}} +{{- if $isSingleBinary }} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.singleBinaryFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.singleBinaryLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- if or (not (empty .Values.loki.annotations)) (not (empty .Values.singleBinary.annotations))}} + annotations: + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.singleBinary.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + replicas: {{ include "loki.singleBinaryReplicas" . }} + podManagementPolicy: Parallel + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.singleBinaryFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.singleBinary.persistence.enableStatefulSetAutoDeletePVC) (.Values.singleBinary.persistence.enabled) }} + {{/* + Data on the singleBinary nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete + {{- end }} + selector: + matchLabels: + {{- include "loki.singleBinarySelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.singleBinarySelectorLabels" . | nindent 8 }} + {{- with .Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.selectorLabels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + app.kubernetes.io/part-of: memberlist + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{ include "loki.enableServiceLinks" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.singleBinaryPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.singleBinary.terminationGracePeriodSeconds }} + {{- if .Values.singleBinary.initContainers }} + initContainers: + {{- with .Values.singleBinary.initContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + containers: + {{- if .Values.sidecar.rules.enabled }} + - name: loki-sc-rules + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.image.pullPolicy }} + env: + - name: METHOD + value: {{ .Values.sidecar.rules.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.rules.label }}" + {{- if .Values.sidecar.rules.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.rules.labelValue }} + {{- end }} + - name: FOLDER + value: "{{ .Values.sidecar.rules.folder }}" + - name: RESOURCE + value: {{ quote .Values.sidecar.rules.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.rules.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.rules.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + {{- if .Values.sidecar.rules.script }} + - name: SCRIPT + value: "{{ .Values.sidecar.rules.script }}" + {{- end }} + {{- if .Values.sidecar.rules.watchServerTimeout }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.rules.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.rules.watchClientTimeout }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.rules.watchClientTimeout }}" + {{- end }} + {{- if .Values.sidecar.rules.logLevel }} + - name: LOG_LEVEL + value: "{{ .Values.sidecar.rules.logLevel }}" + {{- end }} + {{- if .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml .Values.sidecar.livenessProbe | nindent 12 }} + {{- end }} + {{- if .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml .Values.sidecar.readinessProbe | nindent 12 }} + {{- end }} + {{- if .Values.sidecar.resources }} + resources: + {{- toYaml .Values.sidecar.resources | nindent 12 }} + {{- end }} + {{- if .Values.sidecar.securityContext }} + securityContext: + {{- toYaml .Values.sidecar.securityContext | nindent 12 }} + {{- end }} + volumeMounts: + - name: sc-rules-volume + mountPath: {{ .Values.sidecar.rules.folder | quote }} + {{- end}} + - name: loki + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target={{ .Values.singleBinary.targetModule }} + {{- with .Values.singleBinary.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.loki.server.http_listen_port }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.loki.server.grpc_listen_port }} + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with .Values.singleBinary.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.singleBinary.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + {{- if .Values.singleBinary.persistence.enabled }} + - name: storage + mountPath: /var/loki + {{- end }} + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- if .Values.sidecar.rules.enabled }} + - name: sc-rules-volume + mountPath: {{ .Values.sidecar.rules.folder | quote }} + {{- end}} + {{- with .Values.singleBinary.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.singleBinary.resources | nindent 12 }} + {{- with .Values.singleBinary.extraContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.singleBinary.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: tmp + emptyDir: {} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- if .Values.sidecar.rules.enabled }} + - name: sc-rules-volume + {{- if .Values.sidecar.rules.sizeLimit }} + emptyDir: + sizeLimit: {{ .Values.sidecar.rules.sizeLimit }} + {{- else }} + emptyDir: {} + {{- end -}} + {{- end -}} + {{- with .Values.singleBinary.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.singleBinary.persistence.enabled }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: storage + {{- with .Values.singleBinary.persistence.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.singleBinary.persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .Values.singleBinary.persistence.size | quote }} + {{- with .Values.singleBinary.persistence.selector }} + selector: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/table-manager/_helpers-table-manager.tpl b/charts/mayastor/charts/loki/templates/table-manager/_helpers-table-manager.tpl new file mode 100644 index 0000000..ff25832 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/table-manager/_helpers-table-manager.tpl @@ -0,0 +1,32 @@ +{{/* +table-manager fullname +*/}} +{{- define "loki.tableManagerFullname" -}} +{{ include "loki.fullname" . }}-table-manager +{{- end }} + +{{/* +table-manager common labels +*/}} +{{- define "loki.tableManagerLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: table-manager +{{- end }} + +{{/* +table-manager selector labels +*/}} +{{- define "loki.tableManagerSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: table-manager +{{- end }} + +{{/* +table-manager priority class name +*/}} +{{- define "loki.tableManagerPriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.tableManager.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/table-manager/deployment-table-manager.yaml b/charts/mayastor/charts/loki/templates/table-manager/deployment-table-manager.yaml new file mode 100644 index 0000000..770629b --- /dev/null +++ b/charts/mayastor/charts/loki/templates/table-manager/deployment-table-manager.yaml @@ -0,0 +1,126 @@ +{{- if .Values.tableManager.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "loki.tableManagerFullname" . }} + labels: + {{- include "loki.tableManagerLabels" . | nindent 4 }} + annotations: + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.tableManager.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: 1 + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "loki.tableManagerSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tableManager.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.tableManagerSelectorLabels" . | nindent 8 }} + {{- with .Values.loki.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tableManager.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.tableManagerPriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.tableManager.terminationGracePeriodSeconds }} + containers: + - name: table-manager + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target=table-manager + {{- with .Values.tableManager.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.loki.server.http_listen_port }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.loki.server.grpc_listen_port }} + protocol: TCP + {{- with .Values.tableManager.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.tableManager.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + livenessProbe: + {{- toYaml .Values.loki.livenessProbe | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with .Values.tableManager.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.tableManager.resources | nindent 12 }} + {{- if .Values.tableManager.extraContainers }} + {{- toYaml .Values.tableManager.extraContainers | nindent 8}} + {{- end }} + {{- with .Values.tableManager.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tableManager.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.tableManager.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tableManager.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with .Values.tableManager.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/table-manager/service-table-manager.yaml b/charts/mayastor/charts/loki/templates/table-manager/service-table-manager.yaml new file mode 100644 index 0000000..214cd36 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/table-manager/service-table-manager.yaml @@ -0,0 +1,36 @@ +{{- if .Values.tableManager.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.fullname" . }}-table-manager + labels: + {{- include "loki.labels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.tableManager.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + app.kubernetes.io/component: table-manager + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.tableManager.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + selector: + {{- include "loki.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: table-manager +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/table-manager/servicemonitor-table-manager.yaml b/charts/mayastor/charts/loki/templates/table-manager/servicemonitor-table-manager.yaml new file mode 100644 index 0000000..09aa727 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/table-manager/servicemonitor-table-manager.yaml @@ -0,0 +1,57 @@ +{{- if .Values.tableManager.enabled }} +{{- with .Values.serviceMonitor }} +{{- if .enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "loki.tableManagerFullname" $ }} + {{- with .namespace }} + namespace: {{ . }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "loki.tableManagerLabels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- include "loki.tableManagerSelectorLabels" $ | nindent 6 }} + endpoints: + - port: http-metrics + {{- with .interval }} + interval: {{ . }} + {{- end }} + {{- with .scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .scheme }} + scheme: {{ . }} + {{- end }} + {{- with .tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .targetLabels }} + targetLabels: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/tests/_helpers.tpl b/charts/mayastor/charts/loki/templates/tests/_helpers.tpl new file mode 100644 index 0000000..9ef7c15 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/tests/_helpers.tpl @@ -0,0 +1,16 @@ +{{/* +Docker image name for loki helm test +*/}} +{{- define "loki.helmTestImage" -}} +{{- $dict := dict "service" .Values.test.image "global" .Values.global.image "defaultVersion" "latest" -}} +{{- include "loki.baseImage" $dict -}} +{{- end -}} + + +{{/* +test common labels +*/}} +{{- define "loki.helmTestLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: helm-test +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/tests/test-canary.yaml b/charts/mayastor/charts/loki/templates/tests/test-canary.yaml new file mode 100644 index 0000000..4d99228 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/tests/test-canary.yaml @@ -0,0 +1,36 @@ +{{- with .Values.test }} +{{- if (and .enabled $.Values.lokiCanary.enabled) }} +--- +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "loki.name" $ }}-helm-test" + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.helmTestLabels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": test +spec: + containers: + - name: loki-helm-test + image: {{ include "loki.helmTestImage" $ }} + env: + - name: CANARY_SERVICE_ADDRESS + value: "{{ .canaryServiceAddress }}" + - name: CANARY_PROMETHEUS_ADDRESS + value: "{{ .prometheusAddress }}" + {{- with .timeout }} + - name: CANARY_TEST_TIMEOUT + value: "{{ . }}" + {{- end }} + args: + - -test.v + restartPolicy: Never +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/tokengen/_helpers.yaml b/charts/mayastor/charts/loki/templates/tokengen/_helpers.yaml new file mode 100644 index 0000000..3c881f2 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/tokengen/_helpers.yaml @@ -0,0 +1,22 @@ +{{/* +tokengen fullname +*/}} +{{- define "enterprise-logs.tokengenFullname" -}} +{{ include "loki.name" . }}-tokengen +{{- end }} + +{{/* +tokengen common labels +*/}} +{{- define "enterprise-logs.tokengenLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: tokengen +{{- end }} + +{{/* +tokengen selector labels +*/}} +{{- define "enterprise-logs.tokengenSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: tokengen +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/tokengen/clusterrole-tokengen.yaml b/charts/mayastor/charts/loki/templates/tokengen/clusterrole-tokengen.yaml new file mode 100644 index 0000000..d357622 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/tokengen/clusterrole-tokengen.yaml @@ -0,0 +1,21 @@ +{{ if and .Values.enterprise.tokengen.enabled .Values.enterprise.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ if not .Values.rbac.namespaced }}Cluster{{ end }}Role +metadata: + name: {{ template "enterprise-logs.tokengenFullname" . }} + labels: + {{- include "enterprise-logs.tokengenLabels" . | nindent 4 }} + {{- with .Values.enterprise.tokengen.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.tokengen.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["create", "get", "patch"] +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/tokengen/clusterrolebinding-tokengen.yaml b/charts/mayastor/charts/loki/templates/tokengen/clusterrolebinding-tokengen.yaml new file mode 100644 index 0000000..fb21d8f --- /dev/null +++ b/charts/mayastor/charts/loki/templates/tokengen/clusterrolebinding-tokengen.yaml @@ -0,0 +1,25 @@ +{{ if and .Values.enterprise.tokengen.enabled .Values.enterprise.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ if not .Values.rbac.namespaced }}Cluster{{ end }}RoleBinding +metadata: + name: {{ template "enterprise-logs.tokengenFullname" . }} + labels: + {{- include "enterprise-logs.tokengenLabels" . | nindent 4 }} + {{- with .Values.enterprise.tokengen.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.tokengen.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: {{ if not .Values.rbac.namespaced }}Cluster{{ end }}Role + name: {{ template "enterprise-logs.tokengenFullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "enterprise-logs.tokengenFullname" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/tokengen/job-tokengen.yaml b/charts/mayastor/charts/loki/templates/tokengen/job-tokengen.yaml new file mode 100644 index 0000000..b0950d6 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/tokengen/job-tokengen.yaml @@ -0,0 +1,143 @@ +{{ if and .Values.enterprise.tokengen.enabled .Values.enterprise.enabled }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "enterprise-logs.tokengenFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "enterprise-logs.tokengenLabels" . | nindent 4 }} + {{- with .Values.enterprise.tokengen.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.tokengen.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install + "helm.sh/hook-weight": "10" +spec: + backoffLimit: 6 + completions: 1 + parallelism: 1 + template: + metadata: + labels: + {{- include "enterprise-logs.tokengenSelectorLabels" . | nindent 8 }} + {{- with .Values.enterprise.tokengen.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{- with .Values.enterprise.tokengen.annotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.enterprise.tokengen.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + securityContext: + {{- toYaml .Values.enterprise.tokengen.securityContext | nindent 8 }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + initContainers: + - name: loki + image: {{ template "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + # The shared emptyDir exists only while the job is running, and is deleted once the job is completed. + # The tokengen generates a new admin token in case the 'token-file' file doesn't exist. + # As a result, subsequent executions of this tokengen job will generate new admin tokens. + # Note that previously generated tokens remain valid, as these remain present in the object storage. + - -config.file=/etc/loki/config/config.yaml + - -target={{ .Values.enterprise.tokengen.targetModule }} + - -tokengen.token-file=/shared/admin-token + {{- with .Values.enterprise.tokengen.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.enterprise.tokengen.extraVolumeMounts }} + {{ toYaml .Values.enterprise.tokengen.extraVolumeMounts | nindent 12 }} + {{- end }} + - name: shared + mountPath: /shared + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: license + mountPath: /etc/loki/license + env: + {{- if .Values.enterprise.tokengen.env }} + {{ toYaml .Values.enterprise.tokengen.env | nindent 12 }} + {{- end }} + {{- with .Values.enterprise.tokengen.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + containers: + - name: create-secret + image: {{ include "loki.kubectlImage" . }} + imagePullPolicy: {{ .Values.kubectlImage.pullPolicy }} + command: + - /bin/bash + - -euc + - | + # Create or update admin token secrets generated by tokengen job + kubectl create secret generic "{{ include "enterprise-logs.adminTokenSecret" . }}" \ + --from-file=token=/shared/admin-token \ + --dry-run=client -o yaml \ + | kubectl apply -f - + {{- with .Values.enterprise.adminToken.additionalNamespaces }} + {{- range . }} + kubectl --namespace "{{ . }}" create secret generic "{{ include "enterprise-logs.adminTokenSecret" $ }}" \ + --from-file=token=/shared/admin-token \ + --dry-run=client -o yaml \ + | kubectl apply -f - + {{- end }} + {{- end }} + volumeMounts: + {{- if .Values.enterprise.tokengen.extraVolumeMounts }} + {{ toYaml .Values.enterprise.tokengen.extraVolumeMounts | nindent 12 }} + {{- end }} + - name: shared + mountPath: /shared + - name: config + mountPath: /etc/loki/config + - name: license + mountPath: /etc/loki/license + restartPolicy: OnFailure + serviceAccount: {{ template "enterprise-logs.tokengenFullname" . }} + serviceAccountName: {{ template "enterprise-logs.tokengenFullname" . }} + {{- with .Values.enterprise.tokengen.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.enterprise.tokengen.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.enterprise.tokengen.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + - name: shared + emptyDir: {} + {{- if .Values.enterprise.tokengen.extraVolumes }} + {{ toYaml .Values.enterprise.tokengen.extraVolumes | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/tokengen/serviceaccount-tokengen.yaml b/charts/mayastor/charts/loki/templates/tokengen/serviceaccount-tokengen.yaml new file mode 100644 index 0000000..6f0e5a3 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/tokengen/serviceaccount-tokengen.yaml @@ -0,0 +1,18 @@ +{{ if and .Values.enterprise.tokengen.enabled .Values.enterprise.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "enterprise-logs.tokengenFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "enterprise-logs.tokengenLabels" . | nindent 4 }} + {{- with .Values.enterprise.tokengen.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with .Values.enterprise.tokengen.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + "helm.sh/hook": post-install +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/validate.yaml b/charts/mayastor/charts/loki/templates/validate.yaml new file mode 100644 index 0000000..93e2490 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/validate.yaml @@ -0,0 +1,41 @@ +{{- if .Values.config }} +{{- fail "Top level 'config' is not allowed. Most common configuration sections are exposed under the `loki` section. If you need to override the whole config, provide the configuration as a string that can contain template expressions under `loki.config`. Alternatively, you can provide the configuration as an external secret." }} +{{- end }} + +{{- if and (not .Values.lokiCanary.enabled) .Values.test.enabled }} +{{- fail "Helm test requires the Loki Canary to be enabled"}} +{{- end }} + +{{- $singleBinaryReplicas := int .Values.singleBinary.replicas }} +{{- $isUsingFilesystem := eq (include "loki.isUsingObjectStorage" .) "false" }} +{{- $atLeastOneScalableReplica := or (gt (int .Values.backend.replicas) 0) (gt (int .Values.read.replicas) 0) (gt (int .Values.write.replicas) 0) }} +{{- $atLeastOneDistributedReplica := or (gt (int .Values.ingester.replicas) 0) (gt (int .Values.distributor.replicas) 0) (gt (int .Values.querier.replicas) 0) (gt (int .Values.queryFrontend.replicas) 0) (gt (int .Values.queryScheduler.replicas) 0) (gt (int .Values.indexGateway.replicas) 0) (gt (int .Values.compactor.replicas) 0) (gt (int .Values.ruler.replicas) 0) }} + +{{- if and $isUsingFilesystem (gt $singleBinaryReplicas 1) }} +{{- fail "Cannot run more than 1 Single Binary replica without an object storage backend."}} +{{- end }} + +{{- if and $isUsingFilesystem (and (eq $singleBinaryReplicas 0) (or $atLeastOneScalableReplica $atLeastOneDistributedReplica)) }} +{{- fail "Cannot run scalable targets (backend, read, write) or distributed targets without an object storage backend."}} +{{- end }} + +{{- if and $atLeastOneScalableReplica $atLeastOneDistributedReplica (ne .Values.deploymentMode "SimpleScalable<->Distributed") }} +{{- fail "You have more than zero replicas configured for scalable targets (backend, read, write) and distributed targets. If this was intentional change the deploymentMode to the transitional 'SimpleScalable<->Distributed' mode" }} +{{- end }} + +{{- if and (gt $singleBinaryReplicas 0) $atLeastOneDistributedReplica }} +{{- fail "You have more than zero replicas configured for both the single binary and distributed targets, there is no transition mode between these targets please change one or the other to zero or transition to the SimpleScalable mode first."}} +{{- end }} + +{{- if and (gt $singleBinaryReplicas 0) $atLeastOneScalableReplica (ne .Values.deploymentMode "SingleBinary<->SimpleScalable") }} +{{- fail "You have more than zero replicas configured for both the single binary and simple scalable targets. If this was intentional change the deploymentMode to the transitional 'SingleBinary<->SimpleScalable' mode"}} +{{- end }} + +{{- if and (or (not (empty .Values.loki.schemaConfig)) (not (empty .Values.loki.structuredConfig.schema_config))) .Values.loki.useTestSchema }} +{{- fail "loki.useTestSchema must be false if loki.schemaConfig or loki.structuredConfig.schema_config are defined."}} +{{- end }} + + +{{- if and (empty .Values.loki.schemaConfig) (empty .Values.loki.structuredConfig.schema_config) (not .Values.loki.useTestSchema) }} +{{- fail "You must provide a schema_config for Loki, one is not provided as this will be individual for every Loki cluster. See https://grafana.com/docs/loki/latest/operations/storage/schema/ for schema information. For quick testing (with no persistence) add `--set loki.useTestSchema=true`"}} +{{- end }} \ No newline at end of file diff --git a/charts/mayastor/charts/loki/templates/write/_helpers-write.tpl b/charts/mayastor/charts/loki/templates/write/_helpers-write.tpl new file mode 100644 index 0000000..8f526bc --- /dev/null +++ b/charts/mayastor/charts/loki/templates/write/_helpers-write.tpl @@ -0,0 +1,32 @@ +{{/* +write fullname +*/}} +{{- define "loki.writeFullname" -}} +{{ include "loki.name" . }}-write +{{- end }} + +{{/* +write common labels +*/}} +{{- define "loki.writeLabels" -}} +{{ include "loki.labels" . }} +app.kubernetes.io/component: write +{{- end }} + +{{/* +write selector labels +*/}} +{{- define "loki.writeSelectorLabels" -}} +{{ include "loki.selectorLabels" . }} +app.kubernetes.io/component: write +{{- end }} + +{{/* +write priority class name +*/}} +{{- define "loki.writePriorityClassName" -}} +{{- $pcn := coalesce .Values.global.priorityClassName .Values.write.priorityClassName -}} +{{- if $pcn }} +priorityClassName: {{ $pcn }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/write/hpa.yaml b/charts/mayastor/charts/loki/templates/write/hpa.yaml new file mode 100644 index 0000000..ba88ee2 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/write/hpa.yaml @@ -0,0 +1,51 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- $autoscalingv2 := .Capabilities.APIVersions.Has "autoscaling/v2" -}} +{{- if and $isSimpleScalable ( .Values.write.autoscaling.enabled ) }} +{{- if $autoscalingv2 }} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta1 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "loki.writeFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.writeLabels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: StatefulSet + name: {{ include "loki.writeFullname" . }} + minReplicas: {{ .Values.write.autoscaling.minReplicas }} + maxReplicas: {{ .Values.write.autoscaling.maxReplicas }} + {{- with .Values.write.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} + metrics: + {{- with .Values.write.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} + {{- with .Values.write.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if $autoscalingv2 }} + target: + type: Utilization + averageUtilization: {{ . }} + {{- else }} + targetAverageUtilization: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/write/poddisruptionbudget-write.yaml b/charts/mayastor/charts/loki/templates/write/poddisruptionbudget-write.yaml new file mode 100644 index 0000000..24e1356 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/write/poddisruptionbudget-write.yaml @@ -0,0 +1,15 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if and $isSimpleScalable (gt (int .Values.write.replicas) 1) }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "loki.writeFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.writeLabels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "loki.writeSelectorLabels" . | nindent 6 }} + maxUnavailable: 1 +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/write/service-write-headless.yaml b/charts/mayastor/charts/loki/templates/write/service-write-headless.yaml new file mode 100644 index 0000000..84cf5d7 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/write/service-write-headless.yaml @@ -0,0 +1,41 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isSimpleScalable }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.writeFullname" . }}-headless + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.writeSelectorLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.write.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + variant: headless + prometheus.io/service-monitor: "false" + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.write.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + appProtocol: tcp + selector: + {{- include "loki.writeSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/write/service-write.yaml b/charts/mayastor/charts/loki/templates/write/service-write.yaml new file mode 100644 index 0000000..9603706 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/write/service-write.yaml @@ -0,0 +1,37 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isSimpleScalable }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "loki.writeFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.writeLabels" . | nindent 4 }} + {{- with .Values.loki.serviceLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.write.service.labels }} + {{- toYaml . | nindent 4}} + {{- end }} + annotations: + {{- with .Values.loki.serviceAnnotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.write.service.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} +spec: + type: ClusterIP + ports: + - name: http-metrics + port: {{ .Values.loki.server.http_listen_port }} + targetPort: http-metrics + protocol: TCP + - name: grpc + port: {{ .Values.loki.server.grpc_listen_port }} + targetPort: grpc + protocol: TCP + selector: + {{- include "loki.writeSelectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mayastor/charts/loki/templates/write/statefulset-write.yaml b/charts/mayastor/charts/loki/templates/write/statefulset-write.yaml new file mode 100644 index 0000000..97a0818 --- /dev/null +++ b/charts/mayastor/charts/loki/templates/write/statefulset-write.yaml @@ -0,0 +1,211 @@ +{{- $isSimpleScalable := eq (include "loki.deployment.isScalable" .) "true" -}} +{{- if $isSimpleScalable }} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "loki.writeFullname" . }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "loki.writeLabels" . | nindent 4 }} + app.kubernetes.io/part-of: memberlist + {{- if or (not (empty .Values.loki.annotations)) (not (empty .Values.backend.annotations))}} + annotations: + {{- with .Values.loki.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.write.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: +{{- if not .Values.write.autoscaling.enabled }} + {{- if eq .Values.deploymentMode "SingleBinary" }} + replicas: 0 + {{- else }} + replicas: {{ .Values.write.replicas }} + {{- end }} +{{- end }} + podManagementPolicy: {{ .Values.write.podManagementPolicy }} + updateStrategy: + rollingUpdate: + partition: 0 + serviceName: {{ include "loki.writeFullname" . }}-headless + revisionHistoryLimit: {{ .Values.loki.revisionHistoryLimit }} + {{- if and (semverCompare ">= 1.23-0" (include "loki.kubeVersion" .)) (.Values.write.persistence.enableStatefulSetAutoDeletePVC) (.Values.write.persistence.volumeClaimsEnabled) }} + {{/* + Data on the write nodes is easy to replace, so we want to always delete PVCs to make + operation easier, and will rely on re-fetching data when needed. + */}} + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete + {{- end }} + selector: + matchLabels: + {{- include "loki.writeSelectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include "loki.configMapOrSecretContentHash" (dict "ctx" . "name" "/config.yaml") }} + {{- with .Values.loki.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.write.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "loki.writeLabels" . | nindent 8 }} + {{- with merge (dict) .Values.loki.podLabels .Values.write.podLabels }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + app.kubernetes.io/part-of: memberlist + spec: + serviceAccountName: {{ include "loki.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{ include "loki.enableServiceLinks" . }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "loki.writePriorityClassName" . | nindent 6 }} + securityContext: + {{- toYaml .Values.loki.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.write.terminationGracePeriodSeconds }} + {{- if .Values.write.initContainers }} + initContainers: + {{- with .Values.write.initContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + containers: + - name: loki + image: {{ include "loki.image" . }} + imagePullPolicy: {{ .Values.loki.image.pullPolicy }} + args: + - -config.file=/etc/loki/config/config.yaml + - -target={{ .Values.write.targetModule }} + {{- with (concat .Values.global.extraArgs .Values.write.extraArgs) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.loki.server.http_listen_port }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.loki.server.grpc_listen_port }} + protocol: TCP + - name: http-memberlist + containerPort: 7946 + protocol: TCP + {{- with (concat .Values.global.extraEnv .Values.write.extraEnv) | uniq }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with (concat .Values.global.extraEnvFrom .Values.write.extraEnvFrom) | uniq }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + securityContext: + {{- toYaml .Values.loki.containerSecurityContext | nindent 12 }} + readinessProbe: + {{- toYaml .Values.loki.readinessProbe | nindent 12 }} + {{- if .Values.write.lifecycle }} + lifecycle: + {{- toYaml .Values.write.lifecycle | nindent 12 }} + {{- else if .Values.write.autoscaling.enabled }} + lifecycle: + preStop: + httpGet: + path: "/ingester/shutdown?terminate=false" + port: http-metrics + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/loki/config + - name: runtime-config + mountPath: /etc/loki/runtime-config + - name: data + mountPath: /var/loki + {{- if .Values.enterprise.enabled }} + - name: license + mountPath: /etc/loki/license + {{- end }} + {{- with (concat .Values.global.extraVolumeMounts .Values.write.extraVolumeMounts) | uniq }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.write.resources | nindent 12 }} + {{- with .Values.write.extraContainers }} + {{- toYaml . | nindent 8}} + {{- end }} + {{- with .Values.write.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.write.dnsConfig }} + dnsConfig: + {{- tpl . $ | nindent 8 }} + {{- end }} + {{- with .Values.write.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.write.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.write.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + {{- if not .Values.write.persistence.volumeClaimsEnabled }} + - name: data + {{- toYaml .Values.write.persistence.dataVolumeParameters | nindent 10 }} + {{- end}} + - name: config + {{- include "loki.configVolume" . | nindent 10 }} + - name: runtime-config + configMap: + name: {{ template "loki.name" . }}-runtime + {{- if .Values.enterprise.enabled }} + - name: license + secret: + {{- if .Values.enterprise.useExternalLicense }} + secretName: {{ .Values.enterprise.externalLicenseName }} + {{- else }} + secretName: enterprise-logs-license + {{- end }} + {{- end }} + {{- with (concat .Values.global.extraVolumes .Values.write.extraVolumes) | uniq }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.write.persistence.volumeClaimsEnabled }} + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + {{- with .Values.write.persistence.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: + - ReadWriteOnce + {{- with .Values.write.persistence.storageClass }} + storageClassName: {{ if (eq "-" .) }}""{{ else }}{{ . }}{{ end }} + {{- end }} + resources: + requests: + storage: {{ .Values.write.persistence.size | quote }} + {{- with .Values.write.persistence.selector }} + selector: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.write.extraVolumeClaimTemplates }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/loki/test/config_test.go b/charts/mayastor/charts/loki/test/config_test.go new file mode 100644 index 0000000..6926c7b --- /dev/null +++ b/charts/mayastor/charts/loki/test/config_test.go @@ -0,0 +1,220 @@ +package test + +import ( + "os" + "os/exec" + "testing" + + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v2" +) + +type replicas struct { + Replicas int `yaml:"replicas"` +} +type loki struct { + Storage struct { + Type string `yaml:"type"` + } `yaml:"storage"` +} + +type values struct { + DeploymentMode string `yaml:"deploymentMode"` + Backend replicas `yaml:"backend"` + Compactor replicas `yaml:"compactor"` + Distributor replicas `yaml:"distributor"` + IndexGateway replicas `yaml:"indexGateway"` + Ingester replicas `yaml:"ingester"` + Querier replicas `yaml:"querier"` + QueryFrontend replicas `yaml:"queryFrontend"` + QueryScheduler replicas `yaml:"queryScheduler"` + Read replicas `yaml:"read"` + Ruler replicas `yaml:"ruler"` + SingleBinary replicas `yaml:"singleBinary"` + Write replicas `yaml:"write"` + + Loki loki `yaml:"loki"` +} + +func templateConfig(t *testing.T, vals values) error { + y, err := yaml.Marshal(&vals) + require.NoError(t, err) + require.Greater(t, len(y), 0) + + f, err := os.CreateTemp("", "values.yaml") + require.NoError(t, err) + + _, err = f.Write(y) + require.NoError(t, err) + + cmd := exec.Command("helm", "dependency", "build") + // Dependency build needs to be run from the parent directory where the chart is located. + cmd.Dir = "../" + var cmdOutput []byte + if cmdOutput, err = cmd.CombinedOutput(); err != nil { + t.Log("dependency build failed", "err", string(cmdOutput)) + return err + } + + cmd = exec.Command("helm", "template", "../", "--values", f.Name()) + if cmdOutput, err := cmd.CombinedOutput(); err != nil { + t.Log("template failed", "err", string(cmdOutput)) + return err + } + + return nil +} + +// E.Welch these tests fail because the templateConfig function above can't resolve the chart dependencies and I'm not sure how to fix this.... + +//func Test_InvalidConfigs(t *testing.T) { +// t.Run("running both single binary and scalable targets", func(t *testing.T) { +// vals := values{ +// SingleBinary: replicas{Replicas: 1}, +// Write: replicas{Replicas: 1}, +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "gcs"}, +// }, +// } +// require.Error(t, templateConfig(t, vals)) +// }) +// +// t.Run("running both single binary and distributed targets", func(t *testing.T) { +// vals := values{ +// SingleBinary: replicas{Replicas: 1}, +// Distributor: replicas{Replicas: 1}, +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "gcs"}, +// }, +// } +// require.Error(t, templateConfig(t, vals)) +// }) +// +// t.Run("running both scalable and distributed targets", func(t *testing.T) { +// vals := values{ +// Read: replicas{Replicas: 1}, +// Distributor: replicas{Replicas: 1}, +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "gcs"}, +// }, +// } +// require.Error(t, templateConfig(t, vals)) +// }) +// +// t.Run("running scalable with filesystem storage", func(t *testing.T) { +// vals := values{ +// Read: replicas{Replicas: 1}, +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "filesystem"}, +// }, +// } +// +// require.Error(t, templateConfig(t, vals)) +// }) +// +// t.Run("running distributed with filesystem storage", func(t *testing.T) { +// vals := values{ +// Distributor: replicas{Replicas: 1}, +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "filesystem"}, +// }, +// } +// +// require.Error(t, templateConfig(t, vals)) +// }) +//} +// +//func Test_ValidConfigs(t *testing.T) { +// t.Run("single binary", func(t *testing.T) { +// vals := values{ +// +// DeploymentMode: "SingleBinary", +// +// SingleBinary: replicas{Replicas: 1}, +// +// Backend: replicas{Replicas: 0}, +// Compactor: replicas{Replicas: 0}, +// Distributor: replicas{Replicas: 0}, +// IndexGateway: replicas{Replicas: 0}, +// Ingester: replicas{Replicas: 0}, +// Querier: replicas{Replicas: 0}, +// QueryFrontend: replicas{Replicas: 0}, +// QueryScheduler: replicas{Replicas: 0}, +// Read: replicas{Replicas: 0}, +// Ruler: replicas{Replicas: 0}, +// Write: replicas{Replicas: 0}, +// +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "filesystem"}, +// }, +// } +// require.NoError(t, templateConfig(t, vals)) +// }) +// +// t.Run("scalable", func(t *testing.T) { +// vals := values{ +// +// DeploymentMode: "SimpleScalable", +// +// Backend: replicas{Replicas: 1}, +// Read: replicas{Replicas: 1}, +// Write: replicas{Replicas: 1}, +// +// Compactor: replicas{Replicas: 0}, +// Distributor: replicas{Replicas: 0}, +// IndexGateway: replicas{Replicas: 0}, +// Ingester: replicas{Replicas: 0}, +// Querier: replicas{Replicas: 0}, +// QueryFrontend: replicas{Replicas: 0}, +// QueryScheduler: replicas{Replicas: 0}, +// Ruler: replicas{Replicas: 0}, +// SingleBinary: replicas{Replicas: 0}, +// +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "gcs"}, +// }, +// } +// require.NoError(t, templateConfig(t, vals)) +// }) +// +// t.Run("distributed", func(t *testing.T) { +// vals := values{ +// DeploymentMode: "Distributed", +// +// Compactor: replicas{Replicas: 1}, +// Distributor: replicas{Replicas: 1}, +// IndexGateway: replicas{Replicas: 1}, +// Ingester: replicas{Replicas: 1}, +// Querier: replicas{Replicas: 1}, +// QueryFrontend: replicas{Replicas: 1}, +// QueryScheduler: replicas{Replicas: 1}, +// Ruler: replicas{Replicas: 1}, +// +// Backend: replicas{Replicas: 0}, +// Read: replicas{Replicas: 0}, +// SingleBinary: replicas{Replicas: 0}, +// Write: replicas{Replicas: 0}, +// +// Loki: loki{ +// Storage: struct { +// Type string `yaml:"type"` +// }{Type: "gcs"}, +// }, +// } +// require.NoError(t, templateConfig(t, vals)) +// }) +//} diff --git a/charts/mayastor/charts/loki/values.yaml b/charts/mayastor/charts/loki/values.yaml new file mode 100644 index 0000000..32181d7 --- /dev/null +++ b/charts/mayastor/charts/loki/values.yaml @@ -0,0 +1,3793 @@ +# -- Overrides the version used to determine compatibility of resources with the target Kubernetes cluster. +# This is useful when using `helm template`, because then helm will use the client version of kubectl as the Kubernetes version, +# which may or may not match your cluster's server version. Example: 'v1.24.4'. Set to null to use the version that helm +# devises. +kubeVersionOverride: null + +global: + image: + # -- Overrides the Docker registry globally for all images + registry: null + # -- Overrides the priorityClassName for all pods + priorityClassName: null + # -- configures cluster domain ("cluster.local" by default) + clusterDomain: "cluster.local" + # -- configures DNS service name + dnsService: "kube-dns" + # -- configures DNS service namespace + dnsNamespace: "kube-system" + # -- Common additional CLI arguments for all jobs (that is, -log.level debug, -config.expand-env=true or -log-config-reverse-order) + # scope: admin-api, backend, bloom-builder, bloom-gateway, bloom-planner, compactor, distributor, index-gateway, ingester, overrides-exporter, pattern-ingester, querier, query-frontend, query-scheduler, read, ruler, write. + extraArgs: [] + # -- Common environment variables to add to all pods directly managed by this chart. + # scope: admin-api, backend, bloom-builder, bloom-gateway, bloom-planner, compactor, distributor, index-gateway, ingester, overrides-exporter, pattern-ingester, querier, query-frontend, query-scheduler, read, ruler, write. + extraEnv: [] + # -- Common source of environment injections to add to all pods directly managed by this chart. + # scope: admin-api, backend, bloom-builder, bloom-gateway, bloom-planner, compactor, distributor, index-gateway, ingester, overrides-exporter, pattern-ingester, querier, query-frontend, query-scheduler, read, ruler, write. + # For example to inject values from a Secret, use: + # extraEnvFrom: + # - secretRef: + # name: mysecret + extraEnvFrom: [] + # -- Common volumes to add to all pods directly managed by this chart. + # scope: admin-api, backend, bloom-builder, bloom-gateway, bloom-planner, compactor, distributor, index-gateway, ingester, overrides-exporter, pattern-ingester, querier, query-frontend, query-scheduler, read, ruler, write. + extraVolumes: [] + # -- Common mount points to add to all pods directly managed by this chart. + # scope: admin-api, backend, bloom-builder, bloom-gateway, bloom-planner, compactor, distributor, index-gateway, ingester, overrides-exporter, pattern-ingester, querier, query-frontend, query-scheduler, read, ruler, write. + extraVolumeMounts: [] +# -- Overrides the chart's name +nameOverride: null +# -- Overrides the chart's computed fullname +fullnameOverride: null +# -- Overrides the chart's cluster label +clusterLabelOverride: null +# -- Image pull secrets for Docker images +imagePullSecrets: [] +# -- Deployment mode lets you specify how to deploy Loki. +# There are 3 options: +# - SingleBinary: Loki is deployed as a single binary, useful for small installs typically without HA, up to a few tens of GB/day. +# - SimpleScalable: Loki is deployed as 3 targets: read, write, and backend. Useful for medium installs easier to manage than distributed, up to a about 1TB/day. +# - Distributed: Loki is deployed as individual microservices. The most complicated but most capable, useful for large installs, typically over 1TB/day. +# There are also 2 additional modes used for migrating between deployment modes: +# - SingleBinary<->SimpleScalable: Migrate from SingleBinary to SimpleScalable (or vice versa) +# - SimpleScalable<->Distributed: Migrate from SimpleScalable to Distributed (or vice versa) +# Note: SimpleScalable and Distributed REQUIRE the use of object storage. +deploymentMode: SimpleScalable +###################################################################################################################### +# +# Base Loki Configs including kubernetes configurations and configurations for Loki itself, +# see below for more specifics on Loki's configuration. +# +###################################################################################################################### +# -- Configuration for running Loki +# @default -- See values.yaml +loki: + # Configures the readiness probe for all of the Loki pods + readinessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 30 + timeoutSeconds: 1 + image: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: grafana/loki + # -- Overrides the image tag whose default is the chart's appVersion + tag: 3.4.2 + # -- Overrides the image tag with an image digest + digest: null + # -- Docker image pull policy + pullPolicy: IfNotPresent + # -- Common annotations for all deployments/StatefulSets + annotations: {} + # -- Common annotations for all pods + podAnnotations: {} + # -- Common labels for all pods + podLabels: {} + # -- Common annotations for all services + serviceAnnotations: {} + # -- Common labels for all services + serviceLabels: {} + # -- The number of old ReplicaSets to retain to allow rollback + revisionHistoryLimit: 10 + # -- The SecurityContext for Loki pods + podSecurityContext: + fsGroup: 10001 + runAsGroup: 10001 + runAsNonRoot: true + runAsUser: 10001 + # -- The SecurityContext for Loki containers + containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + # -- Should enableServiceLinks be enabled. Default to enable + enableServiceLinks: true + ###################################################################################################################### + # + # Loki Configuration + # + # There are several ways to pass configuration to Loki, listing them here in order of our preference for how + # you should use this chart. + # 1. Use the templated value of loki.config below and the corresponding override sections which follow. + # This allows us to set a lot of important Loki configurations and defaults and also allows us to maintain them + # over time as Loki changes and evolves. + # 2. Use the loki.structuredConfig section. + # This will completely override the templated value of loki.config, so you MUST provide the entire Loki config + # including any configuration that we set in loki.config unless you explicitly are trying to change one of those + # values and are not able to do so with the templated sections. + # If you choose this approach the burden is on you to maintain any changes we make to the templated config. + # 3. Use an existing secret or configmap to provide the configuration. + # This option is mostly provided for folks who have external processes which provide or modify the configuration. + # When using this option you can specify a different name for loki.generatedConfigObjectName and configObjectName + # if you have a process which takes the generated config and modifies it, or you can stop the chart from generating + # a config entirely by setting loki.generatedConfigObjectName to + # + ###################################################################################################################### + + # -- Defines what kind of object stores the configuration, a ConfigMap or a Secret. + # In order to move sensitive information (such as credentials) from the ConfigMap/Secret to a more secure location (e.g. vault), it is possible to use [environment variables in the configuration](https://grafana.com/docs/loki/latest/configuration/#use-environment-variables-in-the-configuration). + # Such environment variables can be then stored in a separate Secret and injected via the global.extraEnvFrom value. For details about environment injection from a Secret please see [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/#use-case-as-container-environment-variables). + configStorageType: ConfigMap + # -- The name of the object which Loki will mount as a volume containing the config. + # If the configStorageType is Secret, this will be the name of the Secret, if it is ConfigMap, this will be the name of the ConfigMap. + # The value will be passed through tpl. + configObjectName: '{{ include "loki.name" . }}' + # -- The name of the Secret or ConfigMap that will be created by this chart. + # If empty, no configmap or secret will be created. + # The value will be passed through tpl. + generatedConfigObjectName: '{{ include "loki.name" . }}' + # -- Config file contents for Loki + # @default -- See values.yaml + config: | + {{- if .Values.enterprise.enabled}} + {{- tpl .Values.enterprise.config . }} + {{- else }} + auth_enabled: {{ .Values.loki.auth_enabled }} + {{- end }} + + {{- with .Values.loki.server }} + server: + {{- toYaml . | nindent 2}} + {{- end}} + + pattern_ingester: + enabled: {{ .Values.loki.pattern_ingester.enabled }} + + memberlist: + {{- if .Values.loki.memberlistConfig }} + {{- toYaml .Values.loki.memberlistConfig | nindent 2 }} + {{- else }} + {{- if .Values.loki.extraMemberlistConfig}} + {{- toYaml .Values.loki.extraMemberlistConfig | nindent 2}} + {{- end }} + join_members: + - {{ include "loki.memberlist" . }} + {{- with .Values.migrate.fromDistributed }} + {{- if .enabled }} + - {{ .memberlistService }} + {{- end }} + {{- end }} + {{- end }} + + {{- with .Values.loki.ingester }} + ingester: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- if .Values.loki.commonConfig}} + common: + {{- toYaml .Values.loki.commonConfig | nindent 2}} + storage: + {{- include "loki.commonStorageConfig" . | nindent 4}} + {{- end}} + + {{- with .Values.loki.limits_config }} + limits_config: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + runtime_config: + file: /etc/loki/runtime-config/runtime-config.yaml + + {{- with .Values.chunksCache }} + {{- if .enabled }} + chunk_store_config: + chunk_cache_config: + default_validity: {{ .defaultValidity }} + background: + writeback_goroutines: {{ .writebackParallelism }} + writeback_buffer: {{ .writebackBuffer }} + writeback_size_limit: {{ .writebackSizeLimit }} + memcached: + batch_size: {{ .batchSize }} + parallelism: {{ .parallelism }} + memcached_client: + addresses: dnssrvnoa+_memcached-client._tcp.{{ template "loki.fullname" $ }}-chunks-cache.{{ $.Release.Namespace }}.svc + consistent_hash: true + timeout: {{ .timeout }} + max_idle_conns: 72 + {{- end }} + {{- end }} + + {{- if .Values.loki.schemaConfig }} + schema_config: + {{- toYaml .Values.loki.schemaConfig | nindent 2}} + {{- end }} + + {{- if .Values.loki.useTestSchema }} + schema_config: + {{- toYaml .Values.loki.testSchemaConfig | nindent 2}} + {{- end }} + + {{- if .Values.ruler.enabled }} + {{ include "loki.rulerConfig" . }} + {{- end }} + + {{- if and .Values.loki.storage.use_thanos_objstore .Values.ruler.enabled}} + ruler_storage: + {{- include "loki.rulerThanosStorageConfig" . | nindent 2 }} + {{- end }} + + {{- if or .Values.tableManager.retention_deletes_enabled .Values.tableManager.retention_period }} + table_manager: + retention_deletes_enabled: {{ .Values.tableManager.retention_deletes_enabled }} + retention_period: {{ .Values.tableManager.retention_period }} + {{- end }} + + query_range: + align_queries_with_step: true + {{- with .Values.loki.query_range }} + {{- tpl (. | toYaml) $ | nindent 2 }} + {{- end }} + {{- if .Values.resultsCache.enabled }} + {{- with .Values.resultsCache }} + cache_results: true + results_cache: + cache: + default_validity: {{ .defaultValidity }} + background: + writeback_goroutines: {{ .writebackParallelism }} + writeback_buffer: {{ .writebackBuffer }} + writeback_size_limit: {{ .writebackSizeLimit }} + memcached_client: + consistent_hash: true + addresses: dnssrvnoa+_memcached-client._tcp.{{ template "loki.fullname" $ }}-results-cache.{{ $.Release.Namespace }}.svc + timeout: {{ .timeout }} + update_interval: 1m + {{- end }} + {{- end }} + + {{- with .Values.loki.storage_config }} + storage_config: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.query_scheduler }} + query_scheduler: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.compactor }} + compactor: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.analytics }} + analytics: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- if .Values.loki.ui.enabled }} + ui: + discovery: + join_peers: + - '{{ include "loki.queryFrontendFullname" . }}.{{ $.Release.Namespace }}.svc.{{ .Values.global.clusterDomain }}' + {{- end }} + {{- with .Values.loki.querier }} + querier: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.index_gateway }} + index_gateway: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.frontend }} + frontend: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.frontend_worker }} + frontend_worker: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.distributor }} + distributor: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + tracing: + enabled: {{ .Values.loki.tracing.enabled }} + + {{- with .Values.loki.bloom_build }} + bloom_build: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + + {{- with .Values.loki.bloom_gateway }} + bloom_gateway: + {{- tpl (. | toYaml) $ | nindent 4 }} + {{- end }} + # Should authentication be enabled + auth_enabled: true + # -- memberlist configuration (overrides embedded default) + memberlistConfig: {} + # -- Extra memberlist configuration + extraMemberlistConfig: {} + # -- Tenants list to be created on nginx htpasswd file, with name and password keys + tenants: [] + # -- Check https://grafana.com/docs/loki/latest/configuration/#server for more info on the server configuration. + server: + http_listen_port: 3100 + grpc_listen_port: 9095 + http_server_read_timeout: 600s + http_server_write_timeout: 600s + # -- Limits config + limits_config: + reject_old_samples: true + reject_old_samples_max_age: 168h + max_cache_freshness_per_query: 10m + split_queries_by_interval: 15m + query_timeout: 300s + volume_enabled: true + # -- Provides a reloadable runtime configuration file for some specific configuration + runtimeConfig: {} + # -- Check https://grafana.com/docs/loki/latest/configuration/#common_config for more info on how to provide a common configuration + commonConfig: + path_prefix: /var/loki + replication_factor: 3 + compactor_address: '{{ include "loki.compactorAddress" . }}' + # -- Storage config. Providing this will automatically populate all necessary storage configs in the templated config. + # -- In case of using thanos storage, enable use_thanos_objstore and the configuration should be done inside the object_store section. + storage: + # Loki requires a bucket for chunks and the ruler. GEL requires a third bucket for the admin API. + # Please provide these values if you are using object storage. + # bucketNames: + # chunks: FIXME + # ruler: FIXME + # admin: FIXME + type: s3 + s3: + s3: null + endpoint: null + region: null + secretAccessKey: null + accessKeyId: null + signatureVersion: null + s3ForcePathStyle: false + insecure: false + http_config: {} + # -- Check https://grafana.com/docs/loki/latest/configure/#s3_storage_config for more info on how to provide a backoff_config + backoff_config: {} + disable_dualstack: false + gcs: + chunkBufferSize: 0 + requestTimeout: "0s" + enableHttp2: true + azure: + accountName: null + accountKey: null + connectionString: null + useManagedIdentity: false + useFederatedToken: false + userAssignedId: null + requestTimeout: null + endpointSuffix: null + chunkDelimiter: null + swift: + auth_version: null + auth_url: null + internal: null + username: null + user_domain_name: null + user_domain_id: null + user_id: null + password: null + domain_id: null + domain_name: null + project_id: null + project_name: null + project_domain_id: null + project_domain_name: null + region_name: null + container_name: null + max_retries: null + connect_timeout: null + request_timeout: null + filesystem: + chunks_directory: /var/loki/chunks + rules_directory: /var/loki/rules + admin_api_directory: /var/loki/admin + + # Loki now supports using thanos storage clients for connecting to object storage backend. + # This will become the default way to configure storage in a future releases. + use_thanos_objstore: false + + object_store: + # Type of object store. Valid options are: s3, gcs, azure + type: s3 + # Optional prefix for storage keys + storage_prefix: null + # S3 configuration (when type is "s3") + s3: + # S3 endpoint URL + endpoint: null + # Optional region + region: null + # Optional access key + access_key_id: null + # Optional secret key + secret_access_key: null + # Optional. Enable if using self-signed TLS + insecure: false + # Optional server-side encryption configuration + sse: {} + # Optional HTTP client configuration + http: {} + + # GCS configuration (when type is "gcs") + gcs: + # Name of the bucket + bucket_name: null + # Optional service account JSON + service_account: null + + # Azure configuration (when type is "azure") + azure: + # Storage account name + account_name: null + # Optional storage account key + account_key: null + + # -- Configure memcached as an external cache for chunk and results cache. Disabled by default + # must enable and specify a host for each cache you would like to use. + memcached: + chunk_cache: + enabled: false + host: "" + service: "memcached-client" + batch_size: 256 + parallelism: 10 + results_cache: + enabled: false + host: "" + service: "memcached-client" + timeout: "500ms" + default_validity: "12h" + # -- Check https://grafana.com/docs/loki/latest/configuration/#schema_config for more info on how to configure schemas + schemaConfig: {} + # -- a real Loki install requires a proper schemaConfig defined above this, however for testing or playing around + # you can enable useTestSchema + useTestSchema: false + testSchemaConfig: + configs: + - from: 2024-04-01 + store: tsdb + object_store: '{{ include "loki.testSchemaObjectStore" . }}' + schema: v13 + index: + prefix: index_ + period: 24h + # -- Check https://grafana.com/docs/loki/latest/configuration/#ruler for more info on configuring ruler + rulerConfig: + wal: + dir: /var/loki/ruler-wal + # -- Structured loki configuration, takes precedence over `loki.config`, `loki.schemaConfig`, `loki.storageConfig` + structuredConfig: {} + # -- Additional query scheduler config + query_scheduler: {} + # -- Additional storage config + storage_config: + boltdb_shipper: + index_gateway_client: + server_address: '{{ include "loki.indexGatewayAddress" . }}' + tsdb_shipper: + index_gateway_client: + server_address: '{{ include "loki.indexGatewayAddress" . }}' + bloom_shipper: + working_directory: /var/loki/data/bloomshipper + hedging: + at: "250ms" + max_per_second: 20 + up_to: 3 + # -- Optional compactor configuration + compactor: {} + # -- Optional pattern ingester configuration + pattern_ingester: + enabled: false + # -- Optional analytics configuration + analytics: {} + # -- Optional Loki UI: Provides access to a operators UI for Loki distributed. When enabled UI will be available at /ui/ of loki-gateway + ui: + # Disabled by default for backwards compatibility. Enable to use the Loki UI. + enabled: false + gateway: + # enable gateway proxying to UI under /ui + enabled: true + # -- Optional querier configuration + query_range: {} + # -- Optional querier configuration + querier: {} + # -- Optional ingester configuration + ingester: {} + # -- Optional index gateway configuration + index_gateway: + mode: simple + frontend: + scheduler_address: '{{ include "loki.querySchedulerAddress" . }}' + tail_proxy_url: '{{ include "loki.querierAddress" . }}' + frontend_worker: + scheduler_address: '{{ include "loki.querySchedulerAddress" . }}' + # -- Optional distributor configuration + distributor: {} + # -- Enable tracing + tracing: + enabled: false + bloom_build: + enabled: false + builder: + planner_address: '{{ include "loki.bloomPlannerAddress" . }}' + bloom_gateway: + enabled: false + client: + addresses: '{{ include "loki.bloomGatewayAddresses" . }}' +###################################################################################################################### +# +# Enterprise Loki Configs +# +###################################################################################################################### + +# -- Configuration for running Enterprise Loki +enterprise: + # Enable enterprise features, license must be provided + enabled: false + # Default verion of GEL to deploy + version: 3.4.0 + # -- Optional name of the GEL cluster, otherwise will use .Release.Name + # The cluster name must match what is in your GEL license + cluster_name: null + # -- Grafana Enterprise Logs license + # In order to use Grafana Enterprise Logs features, you will need to provide + # the contents of your Grafana Enterprise Logs license, either by providing the + # contents of the license.jwt, or the name Kubernetes Secret that contains your + # license.jwt. + # To set the license contents, use the flag `--set-file 'enterprise.license.contents=./license.jwt'` + license: + contents: "NOTAVALIDLICENSE" + # -- Set to true when providing an external license + useExternalLicense: false + # -- Name of external license secret to use + externalLicenseName: null + # -- Name of the external config secret to use + externalConfigName: "" + # -- Use GEL gateway, if false will use the default nginx gateway + gelGateway: true + # -- If enabled, the correct admin_client storage will be configured. If disabled while running enterprise, + # make sure auth is set to `type: trust`, or that `auth_enabled` is set to `false`. + adminApi: + enabled: true + # enterprise specific sections of the config.yaml file + config: | + {{- if .Values.enterprise.adminApi.enabled }} + admin_client: + {{ include "enterprise-logs.adminAPIStorageConfig" . | nindent 2 }} + {{ end }} + auth: + type: {{ .Values.enterprise.adminApi.enabled | ternary "enterprise" "trust" }} + auth_enabled: {{ .Values.loki.auth_enabled }} + cluster_name: {{ include "loki.clusterName" . }} + license: + path: /etc/loki/license/license.jwt + image: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: grafana/enterprise-logs + # -- Docker image tag + tag: 3.4.1 + # -- Overrides the image tag with an image digest + digest: null + # -- Docker image pull policy + pullPolicy: IfNotPresent + adminToken: + # -- Alternative name for admin token secret, needed by tokengen and provisioner jobs + secret: null + # -- Additional namespace to also create the token in. Useful if your Grafana instance + # is in a different namespace + additionalNamespaces: [] + # -- Alternative name of the secret to store token for the canary + canarySecret: null + # -- Configuration for `tokengen` target + tokengen: + # -- Whether the job should be part of the deployment + enabled: true + # -- Comma-separated list of Loki modules to load for tokengen + targetModule: "tokengen" + # -- Additional CLI arguments for the `tokengen` target + extraArgs: [] + # -- Additional Kubernetes environment + env: [] + # -- Additional labels for the `tokengen` Job + labels: {} + # -- Additional annotations for the `tokengen` Job + annotations: {} + # -- Affinity for tokengen Pods + affinity: {} + # -- Node selector for tokengen Pods + nodeSelector: {} + # -- Tolerations for tokengen Job + tolerations: [] + # -- Additional volumes for Pods + extraVolumes: [] + # -- Additional volume mounts for Pods + extraVolumeMounts: [] + # -- Run containers as user `enterprise-logs(uid=10001)` + securityContext: + runAsNonRoot: true + runAsGroup: 10001 + runAsUser: 10001 + fsGroup: 10001 + # -- Environment variables from secrets or configmaps to add to the tokengen pods + extraEnvFrom: [] + # -- The name of the PriorityClass for tokengen Pods + priorityClassName: "" + # -- Configuration for `provisioner` target + provisioner: + # -- Whether the job should be part of the deployment + enabled: true + # -- Name of the secret to store provisioned tokens in + provisionedSecretPrefix: null + # -- Hook type(s) to customize when the job runs. defaults to post-install + hookType: "post-install" + # -- Additional tenants to be created. Each tenant will get a read and write policy + # and associated token. Tenant must have a name and a namespace for the secret containting + # the token to be created in. For example + # additionalTenants: + # - name: loki + # secretNamespace: grafana + additionalTenants: [] + # -- Additional Kubernetes environment + env: [] + # -- Additional labels for the `provisioner` Job + labels: {} + # -- Additional annotations for the `provisioner` Job + annotations: {} + # -- Affinity for tokengen Pods + affinity: {} + # -- Node selector for tokengen Pods + nodeSelector: {} + # -- Tolerations for tokengen Pods + tolerations: [] + # -- The name of the PriorityClass for provisioner Job + priorityClassName: null + # -- Run containers as user `enterprise-logs(uid=10001)` + securityContext: + runAsNonRoot: true + runAsGroup: 10001 + runAsUser: 10001 + fsGroup: 10001 + # -- Provisioner image to Utilize + image: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: grafana/enterprise-logs-provisioner + # -- Overrides the image tag whose default is the chart's appVersion + tag: null + # -- Overrides the image tag with an image digest + digest: null + # -- Docker image pull policy + pullPolicy: IfNotPresent + # -- Volume mounts to add to the provisioner pods + extraVolumeMounts: [] +# -- kubetclImage is used in the enterprise provisioner and tokengen jobs +kubectlImage: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: bitnami/kubectl + # -- Overrides the image tag whose default is the chart's appVersion + tag: null + # -- Overrides the image tag with an image digest + digest: null + # -- Docker image pull policy + pullPolicy: IfNotPresent +###################################################################################################################### +# +# Chart Testing +# +###################################################################################################################### + +# -- Section for configuring optional Helm test +test: + enabled: true + # -- Used to directly query the metrics endpoint of the canary for testing, this approach avoids needing prometheus for testing. + # This in a newer approach to using prometheusAddress such that tests do not have a dependency on prometheus + canaryServiceAddress: "http://loki-canary:3500/metrics" + # -- Address of the prometheus server to query for the test. This overrides any value set for canaryServiceAddress. + # This is kept for backward compatibility and may be removed in future releases. Previous value was 'http://prometheus:9090' + prometheusAddress: "" + # -- Number of times to retry the test before failing + timeout: 1m + # -- Additional labels for the test pods + labels: {} + # -- Additional annotations for test pods + annotations: {} + # -- Image to use for loki canary + image: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: grafana/loki-helm-test + # -- Overrides the image tag whose default is the chart's appVersion + tag: "ewelch-distributed-helm-chart-17db5ee" + # -- Overrides the image tag with an image digest + digest: null + # -- Docker image pull policy + pullPolicy: IfNotPresent +# The Loki canary pushes logs to and queries from this loki installation to test +# that it's working correctly +lokiCanary: + enabled: true + # -- If true, the canary will send directly to Loki via the address configured for verification -- + # -- If false, it will write to stdout and an Agent will be needed to scrape and send the logs -- + push: true + # -- The name of the label to look for at loki when doing the checks. + labelname: pod + # -- Additional annotations for the `loki-canary` Daemonset + annotations: {} + # -- Additional labels for each `loki-canary` pod + podLabels: {} + service: + # -- Annotations for loki-canary Service + annotations: {} + # -- Additional labels for loki-canary Service + labels: {} + # -- Additional CLI arguments for the `loki-canary' command + extraArgs: [] + # -- Environment variables to add to the canary pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the canary pods + extraEnvFrom: [] + # -- Volume mounts to add to the canary pods + extraVolumeMounts: [] + # -- Volumes to add to the canary pods + extraVolumes: [] + # -- Resource requests and limits for the canary + resources: {} + # -- DNS config for canary pods + dnsConfig: {} + # -- Node selector for canary pods + nodeSelector: {} + # -- Tolerations for canary pods + tolerations: [] + # -- The name of the PriorityClass for loki-canary pods + priorityClassName: null + # -- Image to use for loki canary + image: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: grafana/loki-canary + # -- Overrides the image tag whose default is the chart's appVersion + tag: null + # -- Overrides the image tag with an image digest + digest: null + # -- Docker image pull policy + pullPolicy: IfNotPresent + # -- Update strategy for the `loki-canary` Daemonset pods + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 +###################################################################################################################### +# +# Service Accounts and Kubernetes RBAC +# +###################################################################################################################### +serviceAccount: + # -- Specifies whether a ServiceAccount should be created + create: true + # -- The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: null + # -- Image pull secrets for the service account + imagePullSecrets: [] + # -- Annotations for the service account + annotations: {} + # -- Labels for the service account + labels: {} + # -- Set this toggle to false to opt out of automounting API credentials for the service account + automountServiceAccountToken: true +# RBAC configuration +rbac: + # -- If pspEnabled true, a PodSecurityPolicy is created for K8s that use psp. + pspEnabled: false + # -- For OpenShift set pspEnabled to 'false' and sccEnabled to 'true' to use the SecurityContextConstraints. + sccEnabled: false + # -- Specify PSP annotations + # Ref: https://kubernetes.io/docs/reference/access-authn-authz/psp-to-pod-security-standards/#podsecuritypolicy-annotations + pspAnnotations: {} + # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' + # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + # -- Whether to install RBAC in the namespace only or cluster-wide. Useful if you want to watch ConfigMap globally. + namespaced: false +###################################################################################################################### +# +# Network Policy configuration +# +###################################################################################################################### +networkPolicy: + # -- Specifies whether Network Policies should be created + enabled: false + # -- Specifies whether the policies created will be standard Network Policies (flavor: kubernetes) + # or Cilium Network Policies (flavor: cilium) + flavor: kubernetes + metrics: + # -- Specifies the Pods which are allowed to access the metrics port. + # As this is cross-namespace communication, you also need the namespaceSelector. + podSelector: {} + # -- Specifies the namespaces which are allowed to access the metrics port + namespaceSelector: {} + # -- Specifies specific network CIDRs which are allowed to access the metrics port. + # In case you use namespaceSelector, you also have to specify your kubelet networks here. + # The metrics ports are also used for probes. + cidrs: [] + ingress: + # -- Specifies the Pods which are allowed to access the http port. + # As this is cross-namespace communication, you also need the namespaceSelector. + podSelector: {} + # -- Specifies the namespaces which are allowed to access the http port + namespaceSelector: {} + alertmanager: + # -- Specify the alertmanager port used for alerting + port: 9093 + # -- Specifies the alertmanager Pods. + # As this is cross-namespace communication, you also need the namespaceSelector. + podSelector: {} + # -- Specifies the namespace the alertmanager is running in + namespaceSelector: {} + externalStorage: + # -- Specify the port used for external storage, e.g. AWS S3 + ports: [] + # -- Specifies specific network CIDRs you want to limit access to + cidrs: [] + discovery: + # -- (int) Specify the port used for discovery + port: null + # -- Specifies the Pods labels used for discovery. + # As this is cross-namespace communication, you also need the namespaceSelector. + podSelector: {} + # -- Specifies the namespace the discovery Pods are running in + namespaceSelector: {} + egressWorld: + # -- Enable additional cilium egress rules to external world for write, read and backend. + enabled: false + egressKubeApiserver: + # -- Enable additional cilium egress rules to kube-apiserver for backend. + enabled: false +###################################################################################################################### +# +# Global memberlist configuration +# +###################################################################################################################### + +# Configuration for the memberlist service +memberlist: + service: + publishNotReadyAddresses: false + annotations: {} +###################################################################################################################### +# +# adminAPI configuration, enterprise only. +# +###################################################################################################################### + +# -- Configuration for the `admin-api` target +adminApi: + # -- Define the amount of instances + replicas: 1 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + # -- Additional CLI arguments for the `admin-api` target + extraArgs: {} + # -- Environment variables from secrets or configmaps to add to the admin-api pods + extraEnvFrom: [] + # -- Additional labels for the `admin-api` Deployment + labels: {} + # -- Additional annotations for the `admin-api` Deployment + annotations: {} + # -- Additional labels and annotations for the `admin-api` Service + service: + labels: {} + annotations: {} + # -- Run container as user `enterprise-logs(uid=10001)` + # `fsGroup` must not be specified, because these security options are applied + # on container level not on Pod level. + podSecurityContext: + runAsNonRoot: true + runAsGroup: 10001 + runAsUser: 10001 + containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + # -- Update strategy + strategy: + type: RollingUpdate + # -- Readiness probe + readinessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 45 + # -- Request and limit Kubernetes resources + # -- Values are defined in small.yaml and large.yaml + resources: {} + # -- Configure optional environment variables + env: [] + # -- Configure optional initContainers + initContainers: [] + # -- Conifgure optional extraContainers + extraContainers: [] + # -- Additional volumes for Pods + extraVolumes: [] + # -- Additional volume mounts for Pods + extraVolumeMounts: [] + # -- Affinity for admin-api Pods + affinity: {} + # -- Node selector for admin-api Pods + nodeSelector: {} + # -- Topology Spread Constraints for admin-api pods + topologySpreadConstraints: [] + # -- Tolerations for admin-api Pods + tolerations: [] + # -- Grace period to allow the admin-api to shutdown before it is killed + terminationGracePeriodSeconds: 60 +###################################################################################################################### +# +# Gateway and Ingress +# +# By default this chart will deploy a Nginx container to act as a gateway which handles routing of traffic +# and can also do auth. +# +# If you would prefer you can optionally disable this and enable using k8s ingress to do the incoming routing. +# +###################################################################################################################### + +# Configuration for the gateway +gateway: + # -- Specifies whether the gateway should be enabled + enabled: true + # -- Number of replicas for the gateway + replicas: 1 + # -- Default container port + containerPort: 8080 + # -- Enable logging of 2xx and 3xx HTTP requests + verboseLogging: true + autoscaling: + # -- Enable autoscaling for the gateway + enabled: false + # -- Minimum autoscaling replicas for the gateway + minReplicas: 1 + # -- Maximum autoscaling replicas for the gateway + maxReplicas: 3 + # -- Target CPU utilisation percentage for the gateway + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the gateway + targetMemoryUtilizationPercentage: + # -- See `kubectl explain deployment.spec.strategy` for more + # -- ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy + # -- Behavior policies while scaling. + behavior: {} + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 60 + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + deploymentStrategy: + type: RollingUpdate + image: + # -- The Docker registry for the gateway image + registry: docker.io + # -- The gateway image repository + repository: nginxinc/nginx-unprivileged + # -- The gateway image tag + tag: 1.27-alpine + # -- Overrides the gateway image tag with an image digest + digest: null + # -- The gateway image pull policy + pullPolicy: IfNotPresent + # -- The name of the PriorityClass for gateway pods + priorityClassName: null + # -- Annotations for gateway deployment + annotations: {} + # -- Annotations for gateway pods + podAnnotations: {} + # -- Additional labels for gateway pods + podLabels: {} + # -- Additional CLI args for the gateway + extraArgs: [] + # -- Environment variables to add to the gateway pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the gateway pods + extraEnvFrom: [] + # -- Lifecycle for the gateway container + lifecycle: {} + # -- Volumes to add to the gateway pods + extraVolumes: [] + # -- Volume mounts to add to the gateway pods + extraVolumeMounts: [] + # -- The SecurityContext for gateway containers + podSecurityContext: + fsGroup: 101 + runAsGroup: 101 + runAsNonRoot: true + runAsUser: 101 + # -- The SecurityContext for gateway containers + containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + # -- Resource requests and limits for the gateway + resources: {} + # -- Containers to add to the gateway pods + extraContainers: [] + # -- Grace period to allow the gateway to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for gateway pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: gateway + topologyKey: kubernetes.io/hostname + # -- DNS config for gateway pods + dnsConfig: {} + # -- Node selector for gateway pods + nodeSelector: {} + # -- Topology Spread Constraints for gateway pods + topologySpreadConstraints: [] + # -- Tolerations for gateway pods + tolerations: [] + # Gateway service configuration + service: + # -- Port of the gateway service + port: 80 + # -- Type of the gateway service + type: ClusterIP + # -- ClusterIP of the gateway service + clusterIP: null + # -- (int) Node port if service type is NodePort + nodePort: null + # -- Load balancer IPO address if service type is LoadBalancer + loadBalancerIP: null + # -- Annotations for the gateway service + annotations: {} + # -- Labels for gateway service + labels: {} + # Gateway ingress configuration + ingress: + # -- Specifies whether an ingress for the gateway should be created + enabled: false + # -- Ingress Class Name. MAY be required for Kubernetes versions >= 1.18 + ingressClassName: "" + # -- Annotations for the gateway ingress + annotations: {} + # -- Labels for the gateway ingress + labels: {} + # -- Hosts configuration for the gateway ingress, passed through the `tpl` function to allow templating + hosts: + - host: gateway.loki.example.com + paths: + - path: / + # -- pathType (e.g. ImplementationSpecific, Prefix, .. etc.) might also be required by some Ingress Controllers + # pathType: Prefix + # -- TLS configuration for the gateway ingress. Hosts passed through the `tpl` function to allow templating + tls: + - secretName: loki-gateway-tls + hosts: + - gateway.loki.example.com + # Basic auth configuration + basicAuth: + # -- Enables basic authentication for the gateway + enabled: false + # -- The basic auth username for the gateway + username: null + # -- The basic auth password for the gateway + password: null + # -- Uses the specified users from the `loki.tenants` list to create the htpasswd file. + # if `loki.tenants` is not set, the `gateway.basicAuth.username` and `gateway.basicAuth.password` are used. + # The value is templated using `tpl`. Override this to use a custom htpasswd, e.g. in case the default causes + # high CPU load. + # @default -- Either `loki.tenants` or `gateway.basicAuth.username` and `gateway.basicAuth.password`. + htpasswd: >- + {{ if .Values.loki.tenants }} + + + {{- range $t := .Values.loki.tenants }} + {{ htpasswd (required "All tenants must have a 'name' set" $t.name) (required "All tenants must have a 'password' set" $t.password) }} + + + {{- end }} + {{ else }} {{ htpasswd (required "'gateway.basicAuth.username' is required" .Values.gateway.basicAuth.username) (required "'gateway.basicAuth.password' is required" .Values.gateway.basicAuth.password) }} {{ end }} + # -- Existing basic auth secret to use. Must contain '.htpasswd' + existingSecret: null + # Configures the readiness probe for the gateway + readinessProbe: + httpGet: + path: / + port: http-metrics + initialDelaySeconds: 15 + timeoutSeconds: 1 + nginxConfig: + # -- Which schema to be used when building URLs. Can be 'http' or 'https'. + schema: http + # -- Enable listener for IPv6, disable on IPv4-only systems + enableIPv6: true + # -- NGINX log format + logFormat: |- + main '$remote_addr - $remote_user [$time_local] $status ' + '"$request" $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + # -- Allows appending custom configuration to the server block + serverSnippet: "" + # -- Allows appending custom configuration to the http block, passed through the `tpl` function to allow templating + httpSnippet: >- + {{ if .Values.loki.tenants }}proxy_set_header X-Scope-OrgID $remote_user;{{ end }} + # -- Allows customizing the `client_max_body_size` directive + clientMaxBodySize: 4M + # -- Whether ssl should be appended to the listen directive of the server block or not. + ssl: false + # -- Override Read URL + customReadUrl: null + # -- Override Write URL + customWriteUrl: null + # -- Override Backend URL + customBackendUrl: null + # -- Allows overriding the DNS resolver address nginx will use. + resolver: "" + # -- Config file contents for Nginx. Passed through the `tpl` function to allow templating + # @default -- See values.yaml + file: | + {{- include "loki.nginxFile" . | indent 2 -}} +# -- If running enterprise and using the default enterprise gateway, configs go here. +enterpriseGateway: + # -- Define the amount of instances + replicas: 1 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + # -- Additional CLI arguments for the `gateway` target + extraArgs: {} + # -- Environment variables from secrets or configmaps to add to the enterprise gateway pods + extraEnvFrom: [] + # -- Additional labels for the `gateway` Pod + labels: {} + # -- Additional annotations for the `gateway` Pod + annotations: {} + # -- Additional labels and annotations for the `gateway` Service + # -- Service overriding service type + service: + type: ClusterIP + labels: {} + annotations: {} + # -- Run container as user `enterprise-logs(uid=10001)` + podSecurityContext: + runAsNonRoot: true + runAsGroup: 10001 + runAsUser: 10001 + fsGroup: 10001 + containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + # -- If you want to use your own proxy URLs, set this to false. + useDefaultProxyURLs: true + # -- update strategy + strategy: + type: RollingUpdate + # -- Readiness probe + readinessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 45 + # -- Request and limit Kubernetes resources + # -- Values are defined in small.yaml and large.yaml + resources: {} + # -- Configure optional environment variables + env: [] + # -- Configure optional initContainers + initContainers: [] + # -- Conifgure optional extraContainers + extraContainers: [] + # -- Additional volumes for Pods + extraVolumes: [] + # -- Additional volume mounts for Pods + extraVolumeMounts: [] + # -- Affinity for gateway Pods + affinity: {} + # -- Node selector for gateway Pods + nodeSelector: {} + # -- Topology Spread Constraints for enterprise-gateway pods + topologySpreadConstraints: [] + # -- Tolerations for gateway Pods + tolerations: [] + # -- Grace period to allow the gateway to shutdown before it is killed + terminationGracePeriodSeconds: 60 +# -- Ingress configuration Use either this ingress or the gateway, but not both at once. +# If you enable this, make sure to disable the gateway. +# You'll need to supply authn configuration for your ingress controller. +ingress: + enabled: false + ingressClassName: "" + annotations: {} + # nginx.ingress.kubernetes.io/auth-type: basic + # nginx.ingress.kubernetes.io/auth-secret: loki-distributed-basic-auth + # nginx.ingress.kubernetes.io/auth-secret-type: auth-map + # nginx.ingress.kubernetes.io/configuration-snippet: | + # proxy_set_header X-Scope-OrgID $remote_user; + labels: {} + # blackbox.monitoring.exclude: "true" + paths: + # -- Paths that are exposed by Loki Distributor. + # If deployment mode is Distributed, the requests are forwarded to the service: `{{"loki.distributorFullname"}}`. + # If deployment mode is SimpleScalable, the requests are forwarded to write k8s service: `{{"loki.writeFullname"}}`. + # If deployment mode is SingleBinary, the requests are forwarded to the central/single k8s service: `{{"loki.singleBinaryFullname"}}` + distributor: + - /api/prom/push + - /loki/api/v1/push + - /otlp/v1/logs + # -- Paths that are exposed by Loki Query Frontend. + # If deployment mode is Distributed, the requests are forwarded to the service: `{{"loki.queryFrontendFullname"}}`. + # If deployment mode is SimpleScalable, the requests are forwarded to write k8s service: `{{"loki.readFullname"}}`. + # If deployment mode is SingleBinary, the requests are forwarded to the central/single k8s service: `{{"loki.singleBinaryFullname"}}` + queryFrontend: + - /api/prom/query + # this path covers labels and labelValues endpoints + - /api/prom/label + - /api/prom/series + - /api/prom/tail + - /loki/api/v1/query + - /loki/api/v1/query_range + - /loki/api/v1/tail + # this path covers labels and labelValues endpoints + - /loki/api/v1/label + - /loki/api/v1/labels + - /loki/api/v1/series + - /loki/api/v1/index/stats + - /loki/api/v1/index/volume + - /loki/api/v1/index/volume_range + - /loki/api/v1/format_query + - /loki/api/v1/detected_field + - /loki/api/v1/detected_fields + - /loki/api/v1/detected_labels + - /loki/api/v1/patterns + # -- Paths that are exposed by Loki Ruler. + # If deployment mode is Distributed, the requests are forwarded to the service: `{{"loki.rulerFullname"}}`. + # If deployment mode is SimpleScalable, the requests are forwarded to k8s service: `{{"loki.backendFullname"}}`. + # If deployment mode is SimpleScalable but `read.legacyReadTarget` is `true`, the requests are forwarded to k8s service: `{{"loki.readFullname"}}`. + # If deployment mode is SingleBinary, the requests are forwarded to the central/single k8s service: `{{"loki.singleBinaryFullname"}}` + ruler: + - /api/prom/rules + - /api/prom/api/v1/rules + - /api/prom/api/v1/alerts + - /loki/api/v1/rules + - /prometheus/api/v1/rules + - /prometheus/api/v1/alerts + # -- Hosts configuration for the ingress, passed through the `tpl` function to allow templating + hosts: + - loki.example.com + # -- TLS configuration for the ingress. Hosts passed through the `tpl` function to allow templating + tls: [] +# - hosts: +# - loki.example.com +# secretName: loki-distributed-tls + +###################################################################################################################### +# +# Migration +# +###################################################################################################################### + +# -- Options that may be necessary when performing a migration from another helm chart +migrate: + # -- When migrating from a distributed chart like loki-distributed or enterprise-logs + fromDistributed: + # -- Set to true if migrating from a distributed helm chart + enabled: false + # -- If migrating from a distributed service, provide the distributed deployment's + # memberlist service DNS so the new deployment can join its ring. + memberlistService: "" +###################################################################################################################### +# +# Single Binary Deployment +# +# For small Loki installations up to a few 10's of GB per day, or for testing and development. +# +###################################################################################################################### + +# Configuration for the single binary node(s) +singleBinary: + # -- Number of replicas for the single binary + replicas: 0 + autoscaling: + # -- Enable autoscaling + enabled: false + # -- Minimum autoscaling replicas for the single binary + minReplicas: 1 + # -- Maximum autoscaling replicas for the single binary + maxReplicas: 3 + # -- Target CPU utilisation percentage for the single binary + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the single binary + targetMemoryUtilizationPercentage: + image: + # -- The Docker registry for the single binary image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the single binary image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the single binary image. Overrides `loki.image.tag` + tag: null + # -- The name of the PriorityClass for single binary pods + priorityClassName: null + # -- Annotations for single binary StatefulSet + annotations: {} + # -- Annotations for single binary pods + podAnnotations: {} + # -- Additional labels for each `single binary` pod + podLabels: {} + # -- Additional selector labels for each `single binary` pod + selectorLabels: {} + service: + # -- Annotations for single binary Service + annotations: {} + # -- Additional labels for single binary Service + labels: {} + # -- Comma-separated list of Loki modules to load for the single binary + targetModule: "all" + # -- Labels for single binary service + extraArgs: [] + # -- Environment variables to add to the single binary pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the single binary pods + extraEnvFrom: [] + # -- Extra containers to add to the single binary loki pod + extraContainers: [] + # -- Init containers to add to the single binary pods + initContainers: [] + # -- Volume mounts to add to the single binary pods + extraVolumeMounts: [] + # -- Volumes to add to the single binary pods + extraVolumes: [] + # -- Resource requests and limits for the single binary + resources: {} + # -- Grace period to allow the single binary to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for single binary pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: single-binary + topologyKey: kubernetes.io/hostname + # -- DNS config for single binary pods + dnsConfig: {} + # -- Node selector for single binary pods + nodeSelector: {} + # -- Tolerations for single binary pods + tolerations: [] + persistence: + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: true + # -- Enable persistent disk + enabled: true + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Selector for persistent disk + selector: null + # -- Annotations for volume claim + annotations: {} +###################################################################################################################### +# +# Simple Scalable Deployment (SSD) Mode +# +# For small to medium size Loki deployments up to around 1 TB/day, this is the default mode for this helm chart +# +###################################################################################################################### + +# Configuration for the write pod(s) +write: + # -- Number of replicas for the write + replicas: 3 + autoscaling: + # -- Enable autoscaling for the write. + enabled: false + # -- Minimum autoscaling replicas for the write. + minReplicas: 2 + # -- Maximum autoscaling replicas for the write. + maxReplicas: 6 + # -- Target CPU utilisation percentage for the write. + targetCPUUtilizationPercentage: 60 + # -- Target memory utilization percentage for the write. + targetMemoryUtilizationPercentage: + # -- Behavior policies while scaling. + behavior: + # -- see https://github.com/grafana/loki/blob/main/docs/sources/operations/storage/wal.md#how-to-scale-updown for scaledown details + scaleUp: + policies: + - type: Pods + value: 1 + periodSeconds: 900 + scaleDown: + policies: + - type: Pods + value: 1 + periodSeconds: 1800 + stabilizationWindowSeconds: 3600 + image: + # -- The Docker registry for the write image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the write image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the write image. Overrides `loki.image.tag` + tag: null + # -- The name of the PriorityClass for write pods + priorityClassName: null + # -- Annotations for write StatefulSet + annotations: {} + # -- Annotations for write pods + podAnnotations: {} + # -- Additional labels for each `write` pod + podLabels: {} + # -- Additional selector labels for each `write` pod + selectorLabels: {} + service: + # -- Annotations for write Service + annotations: {} + # -- Additional labels for write Service + labels: {} + # -- Comma-separated list of Loki modules to load for the write + targetModule: "write" + # -- Additional CLI args for the write + extraArgs: [] + # -- Environment variables to add to the write pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the write pods + extraEnvFrom: [] + # -- Lifecycle for the write container + lifecycle: {} + # -- The default /flush_shutdown preStop hook is recommended as part of the ingester + # scaledown process so it's added to the template by default when autoscaling is enabled, + # but it's disabled to optimize rolling restarts in instances that will never be scaled + # down or when using chunks storage with WAL disabled. + # https://github.com/grafana/loki/blob/main/docs/sources/operations/storage/wal.md#how-to-scale-updown + # -- Init containers to add to the write pods + initContainers: [] + # -- Containers to add to the write pods + extraContainers: [] + # -- Volume mounts to add to the write pods + extraVolumeMounts: [] + # -- Volumes to add to the write pods + extraVolumes: [] + # -- volumeClaimTemplates to add to StatefulSet + extraVolumeClaimTemplates: [] + # -- Resource requests and limits for the write + resources: {} + # -- Grace period to allow the write to shutdown before it is killed. Especially for the ingester, + # this must be increased. It must be long enough so writes can be gracefully shutdown flushing/transferring + # all data and to successfully leave the member ring on shutdown. + terminationGracePeriodSeconds: 300 + # -- Affinity for write pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: write + topologyKey: kubernetes.io/hostname + # -- DNS config for write pods + dnsConfig: {} + # -- Node selector for write pods + nodeSelector: {} + # -- Topology Spread Constraints for write pods + topologySpreadConstraints: [] + # -- Tolerations for write pods + tolerations: [] + # -- The default is to deploy all pods in parallel. + podManagementPolicy: "Parallel" + persistence: + # -- Enable volume claims in pod spec + volumeClaimsEnabled: true + # -- Parameters used for the `data` volume when volumeClaimEnabled if false + dataVolumeParameters: + emptyDir: {} + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Selector for persistent disk + selector: null + # -- Annotations for volume claim + annotations: {} +# -- Configuration for the read pod(s) +read: + # -- Number of replicas for the read + replicas: 3 + autoscaling: + # -- Enable autoscaling for the read, this is only used if `queryIndex.enabled: true` + enabled: false + # -- Minimum autoscaling replicas for the read + minReplicas: 2 + # -- Maximum autoscaling replicas for the read + maxReplicas: 6 + # -- Target CPU utilisation percentage for the read + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the read + targetMemoryUtilizationPercentage: + # -- Behavior policies while scaling. + behavior: {} + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 60 + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + image: + # -- The Docker registry for the read image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the read image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the read image. Overrides `loki.image.tag` + tag: null + # -- The name of the PriorityClass for read pods + priorityClassName: null + # -- Annotations for read deployment + annotations: {} + # -- Annotations for read pods + podAnnotations: {} + # -- Additional labels for each `read` pod + podLabels: {} + # -- Additional selector labels for each `read` pod + selectorLabels: {} + service: + # -- Annotations for read Service + annotations: {} + # -- Additional labels for read Service + labels: {} + # -- Comma-separated list of Loki modules to load for the read + targetModule: "read" + # -- Whether or not to use the 2 target type simple scalable mode (read, write) or the + # 3 target type (read, write, backend). Legacy refers to the 2 target type, so true will + # run two targets, false will run 3 targets. + legacyReadTarget: false + # -- Additional CLI args for the read + extraArgs: [] + # -- Containers to add to the read pods + extraContainers: [] + # -- Environment variables to add to the read pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the read pods + extraEnvFrom: [] + # -- Lifecycle for the read container + lifecycle: {} + # -- Volume mounts to add to the read pods + extraVolumeMounts: [] + # -- Volumes to add to the read pods + extraVolumes: [] + # -- Resource requests and limits for the read + resources: {} + # -- Grace period to allow the read to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for read pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: read + topologyKey: kubernetes.io/hostname + # -- DNS config for read pods + dnsConfig: {} + # -- Node selector for read pods + nodeSelector: {} + # -- Topology Spread Constraints for read pods + topologySpreadConstraints: [] + # -- Tolerations for read pods + tolerations: [] + # -- The default is to deploy all pods in parallel. + podManagementPolicy: "Parallel" + # -- read.persistence is used only if legacyReadTarget is set to true + persistence: + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: true + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Selector for persistent disk + selector: null + # -- Annotations for volume claim + annotations: {} +# -- Configuration for the backend pod(s) +backend: + # -- Number of replicas for the backend + replicas: 3 + autoscaling: + # -- Enable autoscaling for the backend. + enabled: false + # -- Minimum autoscaling replicas for the backend. + minReplicas: 3 + # -- Maximum autoscaling replicas for the backend. + maxReplicas: 6 + # -- Target CPU utilization percentage for the backend. + targetCPUUtilizationPercentage: 60 + # -- Target memory utilization percentage for the backend. + targetMemoryUtilizationPercentage: + # -- Behavior policies while scaling. + behavior: {} + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 60 + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + image: + # -- The Docker registry for the backend image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the backend image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the backend image. Overrides `loki.image.tag` + tag: null + # -- The name of the PriorityClass for backend pods + priorityClassName: null + # -- Annotations for backend StatefulSet + annotations: {} + # -- Annotations for backend pods + podAnnotations: {} + # -- Additional labels for each `backend` pod + podLabels: {} + # -- Additional selector labels for each `backend` pod + selectorLabels: {} + service: + # -- Annotations for backend Service + annotations: {} + # -- Additional labels for backend Service + labels: {} + # -- Comma-separated list of Loki modules to load for the backend + targetModule: "backend" + # -- Additional CLI args for the backend + extraArgs: [] + # -- Environment variables to add to the backend pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the backend pods + extraEnvFrom: [] + # -- Init containers to add to the backend pods + initContainers: [] + # -- Containers to add to the backend pods + extraContainers: [] + # -- Volume mounts to add to the backend pods + extraVolumeMounts: [] + # -- Volumes to add to the backend pods + extraVolumes: [] + # -- Resource requests and limits for the backend + resources: {} + # -- Grace period to allow the backend to shutdown before it is killed. Especially for the ingester, + # this must be increased. It must be long enough so backends can be gracefully shutdown flushing/transferring + # all data and to successfully leave the member ring on shutdown. + terminationGracePeriodSeconds: 300 + # -- Affinity for backend pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: backend + topologyKey: kubernetes.io/hostname + # -- DNS config for backend pods + dnsConfig: {} + # -- Node selector for backend pods + nodeSelector: {} + # -- Topology Spread Constraints for backend pods + topologySpreadConstraints: [] + # -- Tolerations for backend pods + tolerations: [] + # -- The default is to deploy all pods in parallel. + podManagementPolicy: "Parallel" + persistence: + # -- Enable volume claims in pod spec + volumeClaimsEnabled: true + # -- Parameters used for the `data` volume when volumeClaimEnabled if false + dataVolumeParameters: + emptyDir: {} + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: true + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Selector for persistent disk + selector: null + # -- Annotations for volume claim + annotations: {} +###################################################################################################################### +# +# Microservices Mode +# +# For large Loki deployments ingesting more than 1 TB/day +# +###################################################################################################################### + +# -- Configuration for the ingester +ingester: + # -- Number of replicas for the ingester, when zoneAwareReplication.enabled is true, the total + # number of replicas will match this value with each zone having 1/3rd of the total replicas. + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + autoscaling: + # -- Enable autoscaling for the ingester + enabled: false + # -- Minimum autoscaling replicas for the ingester + minReplicas: 1 + # -- Maximum autoscaling replicas for the ingester + maxReplicas: 3 + # -- Target CPU utilisation percentage for the ingester + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the ingester + targetMemoryUtilizationPercentage: null + # -- Allows one to define custom metrics using the HPA/v2 schema (for example, Pods, Object or External metrics) + customMetrics: [] + # - type: Pods + # pods: + # metric: + # name: loki_lines_total + # target: + # type: AverageValue + # averageValue: 10k + behavior: + # -- Enable autoscaling behaviours + enabled: false + # -- define scale down policies, must conform to HPAScalingRules + scaleDown: {} + # -- define scale up policies, must conform to HPAScalingRules + scaleUp: {} + image: + # -- The Docker registry for the ingester image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the ingester image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the ingester image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + priorityClassName: null + # -- Labels for ingester pods + podLabels: {} + # -- Annotations for ingester pods + podAnnotations: {} + # -- The name of the PriorityClass for ingester pods + # -- Labels for ingestor service + serviceLabels: {} + # -- Annotations for ingestor service + serviceAnnotations: {} + # -- Additional CLI args for the ingester + extraArgs: [] + # -- Environment variables to add to the ingester pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the ingester pods + extraEnvFrom: [] + # -- Volume mounts to add to the ingester pods + extraVolumeMounts: [] + # -- Volumes to add to the ingester pods + extraVolumes: [] + # -- Resource requests and limits for the ingester + resources: {} + # -- Containers to add to the ingester pods + extraContainers: [] + # -- Init containers to add to the ingester pods + initContainers: [] + # -- Grace period to allow the ingester to shutdown before it is killed. Especially for the ingestor, + # this must be increased. It must be long enough so ingesters can be gracefully shutdown flushing/transferring + # all data and to successfully leave the member ring on shutdown. + terminationGracePeriodSeconds: 300 + # -- Lifecycle for the ingester container + lifecycle: {} + # -- topologySpread for ingester pods. + # @default -- Defaults to allow skew no more than 1 node + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/component: ingester + # -- Affinity for ingester pods. Ignored if zoneAwareReplication is enabled. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: ingester + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: 1 + # -- Node selector for ingester pods + nodeSelector: {} + # -- Tolerations for ingester pods + tolerations: [] + # -- readiness probe settings for ingester pods. If empty, use `loki.readinessProbe` + readinessProbe: {} + # -- liveness probe settings for ingester pods. If empty use `loki.livenessProbe` + livenessProbe: {} + # -- UpdateStrategy for the ingester StatefulSets. + updateStrategy: + # -- One of 'OnDelete' or 'RollingUpdate' + type: RollingUpdate + # -- Optional for updateStrategy.type=RollingUpdate. See [Partitioned rolling updates](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions) in the StatefulSet docs for details. + # rollingUpdate: + # partition: 0 + persistence: + # -- Enable creating PVCs which is required when using boltdb-shipper + enabled: false + # -- Use emptyDir with ramdisk for storage. **Please note that all data in ingester will be lost on pod restart** + inMemory: false + # -- List of the ingester PVCs + # @notationType -- list + claims: + - name: data + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # - name: wal + # size: 150Gi + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + whenDeleted: Retain + whenScaled: Retain + # -- Adds the appProtocol field to the ingester service. This allows ingester to work with istio protocol selection. + appProtocol: + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + grpc: "" + # -- Enabling zone awareness on ingesters will create 3 statefulests where all writes will send a replica to each zone. + # This is primarily intended to accelerate rollout operations by allowing for multiple ingesters within a single + # zone to be shutdown and restart simultaneously (the remaining 2 zones will be guaranteed to have at least one copy + # of the data). + # Note: This can be used to run Loki over multiple cloud provider availability zones however this is not currently + # recommended as Loki is not optimized for this and cross zone network traffic costs can become extremely high + # extremely quickly. Even with zone awareness enabled, it is recommended to run Loki in a single availability zone. + zoneAwareReplication: + # -- Enable zone awareness. + enabled: true + # -- The percent of replicas in each zone that will be restarted at once. In a value of 0-100 + maxUnavailablePct: 33 + # -- zoneA configuration + zoneA: + # -- optionally define a node selector for this zone + nodeSelector: null + # -- optionally define extra affinity rules, by default different zones are not allowed to schedule on the same host + extraAffinity: {} + # -- Specific annotations to add to zone A statefulset + annotations: {} + # -- Specific annotations to add to zone A pods + podAnnotations: {} + zoneB: + # -- optionally define a node selector for this zone + nodeSelector: null + # -- optionally define extra affinity rules, by default different zones are not allowed to schedule on the same host + extraAffinity: {} + # -- Specific annotations to add to zone B statefulset + annotations: {} + # -- Specific annotations to add to zone B pods + podAnnotations: {} + zoneC: + # -- optionally define a node selector for this zone + nodeSelector: null + # -- optionally define extra affinity rules, by default different zones are not allowed to schedule on the same host + extraAffinity: {} + # -- Specific annotations to add to zone C statefulset + annotations: {} + # -- Specific annotations to add to zone C pods + podAnnotations: {} + # -- The migration block allows migrating non zone aware ingesters to zone aware ingesters. + migration: + enabled: false + excludeDefaultZone: false + readPath: false + writePath: false + + # optionally allow adding arbitrary prefix to the ingester rollout-group label + rolloutGroupPrefix: null + # optionally allow adding 'loki-' prefix to ingester name label + addIngesterNamePrefix: false + +# -- Configuration for the distributor +distributor: + # -- Number of replicas for the distributor + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + autoscaling: + # -- Enable autoscaling for the distributor + enabled: false + # -- Minimum autoscaling replicas for the distributor + minReplicas: 1 + # -- Maximum autoscaling replicas for the distributor + maxReplicas: 3 + # -- Target CPU utilisation percentage for the distributor + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the distributor + targetMemoryUtilizationPercentage: null + # -- Allows one to define custom metrics using the HPA/v2 schema (for example, Pods, Object or External metrics) + customMetrics: [] + # - type: Pods + # pods: + # metric: + # name: loki_lines_total + # target: + # type: AverageValue + # averageValue: 10k + behavior: + # -- Enable autoscaling behaviours + enabled: false + # -- define scale down policies, must conform to HPAScalingRules + scaleDown: {} + # -- define scale up policies, must conform to HPAScalingRules + scaleUp: {} + image: + # -- The Docker registry for the distributor image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the distributor image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the distributor image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for distributor pods + priorityClassName: null + # -- Labels for distributor pods + podLabels: {} + # -- Annotations for distributor pods + podAnnotations: {} + # -- Labels for distributor service + serviceLabels: {} + # -- Annotations for distributor service + serviceAnnotations: {} + # -- Additional CLI args for the distributor + extraArgs: [] + # -- Environment variables to add to the distributor pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the distributor pods + extraEnvFrom: [] + # -- Volume mounts to add to the distributor pods + extraVolumeMounts: [] + # -- Volumes to add to the distributor pods + extraVolumes: [] + # -- Resource requests and limits for the distributor + resources: {} + # -- Containers to add to the distributor pods + extraContainers: [] + # -- Grace period to allow the distributor to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for distributor pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: distributor + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Max Surge for distributor pods + maxSurge: 0 + # -- Node selector for distributor pods + nodeSelector: {} + # -- Topology Spread Constraints for distributor pods + topologySpreadConstraints: [] + # -- Tolerations for distributor pods + tolerations: [] + # -- Adds the appProtocol field to the distributor service. This allows distributor to work with istio protocol selection. + appProtocol: + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + grpc: "" +# -- Configuration for the querier +querier: + # -- Number of replicas for the querier + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + autoscaling: + # -- Enable autoscaling for the querier, this is only used if `indexGateway.enabled: true` + enabled: false + # -- Minimum autoscaling replicas for the querier + minReplicas: 1 + # -- Maximum autoscaling replicas for the querier + maxReplicas: 3 + # -- Target CPU utilisation percentage for the querier + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the querier + targetMemoryUtilizationPercentage: null + # -- Allows one to define custom metrics using the HPA/v2 schema (for example, Pods, Object or External metrics) + customMetrics: [] + # - type: External + # external: + # metric: + # name: loki_inflight_queries + # target: + # type: AverageValue + # averageValue: 12 + behavior: + # -- Enable autoscaling behaviours + enabled: false + # -- define scale down policies, must conform to HPAScalingRules + scaleDown: {} + # -- define scale up policies, must conform to HPAScalingRules + scaleUp: {} + image: + # -- The Docker registry for the querier image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the querier image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the querier image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for querier pods + priorityClassName: null + # -- Labels for querier pods + podLabels: {} + # -- Annotations for querier pods + podAnnotations: {} + # -- Labels for querier service + serviceLabels: {} + # -- Annotations for querier service + serviceAnnotations: {} + # -- Additional CLI args for the querier + extraArgs: [] + # -- Environment variables to add to the querier pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the querier pods + extraEnvFrom: [] + # -- Volume mounts to add to the querier pods + extraVolumeMounts: [] + # -- Volumes to add to the querier pods + extraVolumes: [] + # -- Resource requests and limits for the querier + resources: {} + # -- Containers to add to the querier pods + extraContainers: [] + # -- Init containers to add to the querier pods + initContainers: [] + # -- Grace period to allow the querier to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- topologySpread for querier pods. + # @default -- Defaults to allow skew no more then 1 node + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/component: querier + # -- Affinity for querier pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: querier + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Max Surge for querier pods + maxSurge: 0 + # -- Node selector for querier pods + nodeSelector: {} + # -- Tolerations for querier pods + tolerations: [] + # -- DNSConfig for querier pods + dnsConfig: {} + persistence: + # -- Enable creating PVCs for the querier cache + enabled: false + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Annotations for querier PVCs + annotations: {} + # -- Adds the appProtocol field to the querier service. This allows querier to work with istio protocol selection. + appProtocol: + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + grpc: "" +# -- Configuration for the query-frontend +queryFrontend: + # -- Number of replicas for the query-frontend + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + autoscaling: + # -- Enable autoscaling for the query-frontend + enabled: false + # -- Minimum autoscaling replicas for the query-frontend + minReplicas: 1 + # -- Maximum autoscaling replicas for the query-frontend + maxReplicas: 3 + # -- Target CPU utilisation percentage for the query-frontend + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the query-frontend + targetMemoryUtilizationPercentage: null + # -- Allows one to define custom metrics using the HPA/v2 schema (for example, Pods, Object or External metrics) + customMetrics: [] + # - type: Pods + # pods: + # metric: + # name: loki_query_rate + # target: + # type: AverageValue + # averageValue: 100 + behavior: + # -- Enable autoscaling behaviours + enabled: false + # -- define scale down policies, must conform to HPAScalingRules + scaleDown: {} + # -- define scale up policies, must conform to HPAScalingRules + scaleUp: {} + image: + # -- The Docker registry for the query-frontend image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the query-frontend image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the query-frontend image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for query-frontend pods + priorityClassName: null + # -- Labels for query-frontend pods + podLabels: {} + # -- Annotations for query-frontend pods + podAnnotations: {} + # -- Labels for query-frontend service + serviceLabels: {} + # -- Annotations for query-frontend service + serviceAnnotations: {} + # -- Additional CLI args for the query-frontend + extraArgs: [] + # -- Environment variables to add to the query-frontend pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the query-frontend pods + extraEnvFrom: [] + # -- Volume mounts to add to the query-frontend pods + extraVolumeMounts: [] + # -- Volumes to add to the query-frontend pods + extraVolumes: [] + # -- Resource requests and limits for the query-frontend + resources: {} + # -- Containers to add to the query-frontend pods + extraContainers: [] + # -- Grace period to allow the query-frontend to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for query-frontend pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: query-frontend + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Node selector for query-frontend pods + nodeSelector: {} + # -- Topology Spread Constraints for query-frontend pods + topologySpreadConstraints: [] + # -- Tolerations for query-frontend pods + tolerations: [] + # -- Adds the appProtocol field to the queryFrontend service. This allows queryFrontend to work with istio protocol selection. + appProtocol: + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + grpc: "" +# -- Configuration for the query-scheduler +queryScheduler: + # -- Number of replicas for the query-scheduler. + # It should be lower than `-querier.max-concurrent` to avoid generating back-pressure in queriers; + # it's also recommended that this value evenly divides the latter + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the query-scheduler image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the query-scheduler image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the query-scheduler image. Overrides `loki.image.tag` + tag: null + # -- The name of the PriorityClass for query-scheduler pods + priorityClassName: null + # -- Labels for query-scheduler pods + podLabels: {} + # -- Annotations for query-scheduler pods + podAnnotations: {} + # -- Labels for query-scheduler service + serviceLabels: {} + # -- Annotations for query-scheduler service + serviceAnnotations: {} + # -- Additional CLI args for the query-scheduler + extraArgs: [] + # -- Environment variables to add to the query-scheduler pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the query-scheduler pods + extraEnvFrom: [] + # -- Volume mounts to add to the query-scheduler pods + extraVolumeMounts: [] + # -- Volumes to add to the query-scheduler pods + extraVolumes: [] + # -- Resource requests and limits for the query-scheduler + resources: {} + # -- Containers to add to the query-scheduler pods + extraContainers: [] + # -- Grace period to allow the query-scheduler to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for query-scheduler pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: query-scheduler + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: 1 + # -- Node selector for query-scheduler pods + nodeSelector: {} + # -- Topology Spread Constraints for query-scheduler pods + topologySpreadConstraints: [] + # -- Tolerations for query-scheduler pods + tolerations: [] + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" +# -- Configuration for the index-gateway +indexGateway: + # -- Number of replicas for the index-gateway + replicas: 0 + # -- Whether the index gateway should join the memberlist hashring + joinMemberlist: true + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the index-gateway image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the index-gateway image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the index-gateway image. Overrides `loki.image.tag` + tag: null + # -- The name of the PriorityClass for index-gateway pods + priorityClassName: null + # -- Labels for index-gateway pods + podLabels: {} + # -- Annotations for index-gateway pods + podAnnotations: {} + # -- Labels for index-gateway service + serviceLabels: {} + # -- Annotations for index-gateway service + serviceAnnotations: {} + # -- Additional CLI args for the index-gateway + extraArgs: [] + # -- Environment variables to add to the index-gateway pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the index-gateway pods + extraEnvFrom: [] + # -- Volume mounts to add to the index-gateway pods + extraVolumeMounts: [] + # -- Volumes to add to the index-gateway pods + extraVolumes: [] + # -- Resource requests and limits for the index-gateway + resources: {} + # -- Containers to add to the index-gateway pods + extraContainers: [] + # -- Init containers to add to the index-gateway pods + initContainers: [] + # -- Grace period to allow the index-gateway to shutdown before it is killed. + terminationGracePeriodSeconds: 300 + # -- Affinity for index-gateway pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: index-gateway + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Node selector for index-gateway pods + nodeSelector: {} + # -- Topology Spread Constraints for index-gateway pods + topologySpreadConstraints: [] + # -- Tolerations for index-gateway pods + tolerations: [] + persistence: + # -- Enable creating PVCs which is required when using boltdb-shipper + enabled: false + # -- Use emptyDir with ramdisk for storage. **Please note that all data in indexGateway will be lost on pod restart** + inMemory: false + # -- Size of persistent or memory disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Annotations for index gateway PVCs + annotations: {} + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + whenDeleted: Retain + whenScaled: Retain + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + # -- UpdateStrategy for the indexGateway StatefulSet. + updateStrategy: + # -- One of 'OnDelete' or 'RollingUpdate' + type: RollingUpdate + # -- Optional for updateStrategy.type=RollingUpdate. See [Partitioned rolling updates](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions) in the StatefulSet docs for details. + # rollingUpdate: + # partition: 0 +# -- Configuration for the compactor +compactor: + # -- Number of replicas for the compactor + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the compactor image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the compactor image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the compactor image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for compactor pods + priorityClassName: null + # -- Labels for compactor pods + podLabels: {} + # -- Annotations for compactor pods + podAnnotations: {} + # -- Affinity for compactor pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: compactor + topologyKey: kubernetes.io/hostname + # -- Labels for compactor service + serviceLabels: {} + # -- Annotations for compactor service + serviceAnnotations: {} + # -- Additional CLI args for the compactor + extraArgs: [] + # -- Environment variables to add to the compactor pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the compactor pods + extraEnvFrom: [] + # -- Volume mounts to add to the compactor pods + extraVolumeMounts: [] + # -- Volumes to add to the compactor pods + extraVolumes: [] + # -- readiness probe settings for ingester pods. If empty, use `loki.readinessProbe` + readinessProbe: {} + # -- liveness probe settings for ingester pods. If empty use `loki.livenessProbe` + livenessProbe: {} + # -- Resource requests and limits for the compactor + resources: {} + # -- Containers to add to the compactor pods + extraContainers: [] + # -- Init containers to add to the compactor pods + initContainers: [] + # -- Grace period to allow the compactor to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Node selector for compactor pods + nodeSelector: {} + # -- Tolerations for compactor pods + tolerations: [] + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + persistence: + # -- Enable creating PVCs for the compactor + enabled: false + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Annotations for compactor PVCs + annotations: {} + # -- List of the compactor PVCs + # @notationType -- list + claims: + - name: data + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # - name: wal + # size: 150Gi + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + whenDeleted: Retain + whenScaled: Retain + serviceAccount: + create: false + # -- The name of the ServiceAccount to use for the compactor. + # If not set and create is true, a name is generated by appending + # "-compactor" to the common ServiceAccount. + name: null + # -- Image pull secrets for the compactor service account + imagePullSecrets: [] + # -- Annotations for the compactor service account + annotations: {} + # -- Set this toggle to false to opt out of automounting API credentials for the service account + automountServiceAccountToken: true +# -- Configuration for the bloom-gateway +bloomGateway: + # -- Number of replicas for the bloom-gateway + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the bloom-gateway image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the bloom-gateway image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the bloom-gateway image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for bloom-gateway pods + priorityClassName: null + # -- Labels for bloom-gateway pods + podLabels: {} + # -- Annotations for bloom-gateway pods + podAnnotations: {} + # -- Affinity for bloom-gateway pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: bloom-gateway + topologyKey: kubernetes.io/hostname + # -- Labels for bloom-gateway service + serviceLabels: {} + # -- Annotations for bloom-gateway service + serviceAnnotations: {} + # -- Additional CLI args for the bloom-gateway + extraArgs: [] + # -- Environment variables to add to the bloom-gateway pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the bloom-gateway pods + extraEnvFrom: [] + # -- Volume mounts to add to the bloom-gateway pods + extraVolumeMounts: [] + # -- Volumes to add to the bloom-gateway pods + extraVolumes: [] + # -- readiness probe settings for ingester pods. If empty, use `loki.readinessProbe` + readinessProbe: {} + # -- liveness probe settings for ingester pods. If empty use `loki.livenessProbe` + livenessProbe: {} + # -- Resource requests and limits for the bloom-gateway + resources: {} + # -- Containers to add to the bloom-gateway pods + extraContainers: [] + # -- Init containers to add to the bloom-gateway pods + initContainers: [] + # -- Grace period to allow the bloom-gateway to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Node selector for bloom-gateway pods + nodeSelector: {} + # -- Tolerations for bloom-gateway pods + tolerations: [] + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + persistence: + # -- Enable creating PVCs for the bloom-gateway + enabled: false + # -- Annotations for bloom-gateway PVCs + annotations: {} + # -- List of the bloom-gateway PVCs + # @notationType -- list + claims: + - name: data + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + whenDeleted: Retain + whenScaled: Retain + serviceAccount: + create: false + # -- The name of the ServiceAccount to use for the bloom-gateway. + # If not set and create is true, a name is generated by appending + # "-bloom-gateway" to the common ServiceAccount. + name: null + # -- Image pull secrets for the bloom-gateway service account + imagePullSecrets: [] + # -- Annotations for the bloom-gateway service account + annotations: {} + # -- Set this toggle to false to opt out of automounting API credentials for the service account + automountServiceAccountToken: true +# -- Configuration for the bloom-planner +bloomPlanner: + # -- Number of replicas for the bloom-planner + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the bloom-planner image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the bloom-planner image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the bloom-planner image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for bloom-planner pods + priorityClassName: null + # -- Labels for bloom-planner pods + podLabels: {} + # -- Annotations for bloom-planner pods + podAnnotations: {} + # -- Affinity for bloom-planner pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: bloom-planner + topologyKey: kubernetes.io/hostname + # -- Labels for bloom-planner service + serviceLabels: {} + # -- Annotations for bloom-planner service + serviceAnnotations: {} + # -- Additional CLI args for the bloom-planner + extraArgs: [] + # -- Environment variables to add to the bloom-planner pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the bloom-planner pods + extraEnvFrom: [] + # -- Volume mounts to add to the bloom-planner pods + extraVolumeMounts: [] + # -- Volumes to add to the bloom-planner pods + extraVolumes: [] + # -- readiness probe settings for ingester pods. If empty, use `loki.readinessProbe` + readinessProbe: {} + # -- liveness probe settings for ingester pods. If empty use `loki.livenessProbe` + livenessProbe: {} + # -- Resource requests and limits for the bloom-planner + resources: {} + # -- Containers to add to the bloom-planner pods + extraContainers: [] + # -- Init containers to add to the bloom-planner pods + initContainers: [] + # -- Grace period to allow the bloom-planner to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Node selector for bloom-planner pods + nodeSelector: {} + # -- Tolerations for bloom-planner pods + tolerations: [] + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + persistence: + # -- Enable creating PVCs for the bloom-planner + enabled: false + # -- Annotations for bloom-planner PVCs + annotations: {} + # -- List of the bloom-planner PVCs + # @notationType -- list + claims: + - name: data + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + whenDeleted: Retain + whenScaled: Retain + serviceAccount: + create: false + # -- The name of the ServiceAccount to use for the bloom-planner. + # If not set and create is true, a name is generated by appending + # "-bloom-planner" to the common ServiceAccount. + name: null + # -- Image pull secrets for the bloom-planner service account + imagePullSecrets: [] + # -- Annotations for the bloom-planner service account + annotations: {} + # -- Set this toggle to false to opt out of automounting API credentials for the service account + automountServiceAccountToken: true +# -- Configuration for the bloom-builder +bloomBuilder: + # -- Number of replicas for the bloom-builder + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + autoscaling: + # -- Enable autoscaling for the bloom-builder + enabled: false + # -- Minimum autoscaling replicas for the bloom-builder + minReplicas: 1 + # -- Maximum autoscaling replicas for the bloom-builder + maxReplicas: 3 + # -- Target CPU utilisation percentage for the bloom-builder + targetCPUUtilizationPercentage: 60 + # -- Target memory utilisation percentage for the bloom-builder + targetMemoryUtilizationPercentage: null + # -- Allows one to define custom metrics using the HPA/v2 schema (for example, Pods, Object or External metrics) + customMetrics: [] + # - type: Pods + # pods: + # metric: + # name: loki_query_rate + # target: + # type: AverageValue + # averageValue: 100 + behavior: + # -- Enable autoscaling behaviours + enabled: false + # -- define scale down policies, must conform to HPAScalingRules + scaleDown: {} + # -- define scale up policies, must conform to HPAScalingRules + scaleUp: {} + image: + # -- The Docker registry for the bloom-builder image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the bloom-builder image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the bloom-builder image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for bloom-builder pods + priorityClassName: null + # -- Labels for bloom-builder pods + podLabels: {} + # -- Annotations for bloom-builder pods + podAnnotations: {} + # -- Labels for bloom-builder service + serviceLabels: {} + # -- Annotations for bloom-builder service + serviceAnnotations: {} + # -- Additional CLI args for the bloom-builder + extraArgs: [] + # -- Environment variables to add to the bloom-builder pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the bloom-builder pods + extraEnvFrom: [] + # -- Volume mounts to add to the bloom-builder pods + extraVolumeMounts: [] + # -- Volumes to add to the bloom-builder pods + extraVolumes: [] + # -- Resource requests and limits for the bloom-builder + resources: {} + # -- Containers to add to the bloom-builder pods + extraContainers: [] + # -- Grace period to allow the bloom-builder to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for bloom-builder pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: bloom-builder + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Node selector for bloom-builder pods + nodeSelector: {} + # -- Tolerations for bloom-builder pods + tolerations: [] + # -- Adds the appProtocol field to the queryFrontend service. This allows bloomBuilder to work with istio protocol selection. + appProtocol: + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + grpc: "" +# -- Configuration for the pattern ingester +patternIngester: + # -- Number of replicas for the pattern ingester + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the pattern ingester image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the pattern ingester image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the pattern ingester image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for pattern ingester pods + priorityClassName: null + # -- Labels for pattern ingester pods + podLabels: {} + # -- Annotations for pattern ingester pods + podAnnotations: {} + # -- Affinity for pattern ingester pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: pattern-ingester + topologyKey: kubernetes.io/hostname + # -- Labels for pattern ingester service + serviceLabels: {} + # -- Annotations for pattern ingester service + serviceAnnotations: {} + # -- Additional CLI args for the pattern ingester + extraArgs: [] + # -- Environment variables to add to the pattern ingester pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the pattern ingester pods + extraEnvFrom: [] + # -- Volume mounts to add to the pattern ingester pods + extraVolumeMounts: [] + # -- Volumes to add to the pattern ingester pods + extraVolumes: [] + # -- readiness probe settings for ingester pods. If empty, use `loki.readinessProbe` + readinessProbe: {} + # -- liveness probe settings for ingester pods. If empty use `loki.livenessProbe` + livenessProbe: {} + # -- Resource requests and limits for the pattern ingester + resources: {} + # -- Containers to add to the pattern ingester pods + extraContainers: [] + # -- Init containers to add to the pattern ingester pods + initContainers: [] + # -- Grace period to allow the pattern ingester to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Node selector for pattern ingester pods + nodeSelector: {} + # -- Topology Spread Constraints for pattern ingester pods + topologySpreadConstraints: [] + # -- Tolerations for pattern ingester pods + tolerations: [] + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + persistence: + # -- Enable creating PVCs for the pattern ingester + enabled: false + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Annotations for pattern ingester PVCs + annotations: {} + # -- List of the pattern ingester PVCs + # @notationType -- list + claims: + - name: data + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # - name: wal + # size: 150Gi + # -- Enable StatefulSetAutoDeletePVC feature + enableStatefulSetAutoDeletePVC: false + whenDeleted: Retain + whenScaled: Retain + serviceAccount: + create: false + # -- The name of the ServiceAccount to use for the pattern ingester. + # If not set and create is true, a name is generated by appending + # "-pattern-ingester" to the common ServiceAccount. + name: null + # -- Image pull secrets for the pattern ingester service account + imagePullSecrets: [] + # -- Annotations for the pattern ingester service account + annotations: {} + # -- Set this toggle to false to opt out of automounting API credentials for the service account + automountServiceAccountToken: true +# -- Configuration for the ruler +ruler: + # -- The ruler component is optional and can be disabled if desired. + enabled: true + # -- Number of replicas for the ruler + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the ruler image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the ruler image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the ruler image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for ruler pods + priorityClassName: null + # -- Labels for compactor pods + podLabels: {} + # -- Annotations for ruler pods + podAnnotations: {} + # -- Labels for ruler service + serviceLabels: {} + # -- Annotations for ruler service + serviceAnnotations: {} + # -- Additional CLI args for the ruler + extraArgs: [] + # -- Environment variables to add to the ruler pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the ruler pods + extraEnvFrom: [] + # -- Volume mounts to add to the ruler pods + extraVolumeMounts: [] + # -- Volumes to add to the ruler pods + extraVolumes: [] + # -- Resource requests and limits for the ruler + resources: {} + # -- Containers to add to the ruler pods + extraContainers: [] + # -- Init containers to add to the ruler pods + initContainers: [] + # -- Grace period to allow the ruler to shutdown before it is killed + terminationGracePeriodSeconds: 300 + # -- Affinity for ruler pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: ruler + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Node selector for ruler pods + nodeSelector: {} + # -- Topology Spread Constraints for ruler pods + topologySpreadConstraints: [] + # -- Tolerations for ruler pods + tolerations: [] + # -- DNSConfig for ruler pods + dnsConfig: {} + persistence: + # -- Enable creating PVCs which is required when using recording rules + enabled: false + # -- Size of persistent disk + size: 10Gi + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Annotations for ruler PVCs + annotations: {} + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + # -- Directories containing rules files + directories: {} + # tenant_foo: + # rules1.txt: | + # groups: + # - name: should_fire + # rules: + # - alert: HighPercentageError + # expr: | + # sum(rate({app="foo", env="production"} |= "error" [5m])) by (job) + # / + # sum(rate({app="foo", env="production"}[5m])) by (job) + # > 0.05 + # for: 10m + # labels: + # severity: warning + # annotations: + # summary: High error rate + # - name: credentials_leak + # rules: + # - alert: http-credentials-leaked + # annotations: + # message: "{{ $labels.job }} is leaking http basic auth credentials." + # expr: 'sum by (cluster, job, pod) (count_over_time({namespace="prod"} |~ "http(s?)://(\\w+):(\\w+)@" [5m]) > 0)' + # for: 10m + # labels: + # severity: critical + # rules2.txt: | + # groups: + # - name: example + # rules: + # - alert: HighThroughputLogStreams + # expr: sum by(container) (rate({job=~"loki-dev/.*"}[1m])) > 1000 + # for: 2m + # tenant_bar: + # rules1.txt: | + # groups: + # - name: should_fire + # rules: + # - alert: HighPercentageError + # expr: | + # sum(rate({app="foo", env="production"} |= "error" [5m])) by (job) + # / + # sum(rate({app="foo", env="production"}[5m])) by (job) + # > 0.05 + # for: 10m + # labels: + # severity: warning + # annotations: + # summary: High error rate + # - name: credentials_leak + # rules: + # - alert: http-credentials-leaked + # annotations: + # message: "{{ $labels.job }} is leaking http basic auth credentials." + # expr: 'sum by (cluster, job, pod) (count_over_time({namespace="prod"} |~ "http(s?)://(\\w+):(\\w+)@" [5m]) > 0)' + # for: 10m + # labels: + # severity: critical + # rules2.txt: | + # groups: + # - name: example + # rules: + # - alert: HighThroughputLogStreams + # expr: sum by(container) (rate({job=~"loki-dev/.*"}[1m])) > 1000 + # for: 2m + +# -- Configuration for the overrides-exporter +overridesExporter: + # -- The overrides-exporter component is optional and can be disabled if desired. + enabled: false + # -- Number of replicas for the overrides-exporter + replicas: 0 + # -- hostAliases to add + hostAliases: [] + # - ip: 1.2.3.4 + # hostnames: + # - domain.tld + image: + # -- The Docker registry for the overrides-exporter image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the overrides-exporter image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the overrides-exporter image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for overrides-exporter pods + priorityClassName: null + # -- Labels for overrides-exporter pods + podLabels: {} + # -- Annotations for overrides-exporter pods + podAnnotations: {} + # -- Labels for overrides-exporter service + serviceLabels: {} + # -- Annotations for overrides-exporter service + serviceAnnotations: {} + # -- Additional CLI args for the overrides-exporter + extraArgs: [] + # -- Environment variables to add to the overrides-exporter pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the overrides-exporter pods + extraEnvFrom: [] + # -- Volume mounts to add to the overrides-exporter pods + extraVolumeMounts: [] + # -- Volumes to add to the overrides-exporter pods + extraVolumes: [] + # -- Resource requests and limits for the overrides-exporter + resources: {} + # -- Containers to add to the overrides-exporter pods + extraContainers: [] + # -- Init containers to add to the overrides-exporter pods + initContainers: [] + # -- Grace period to allow the overrides-exporter to shutdown before it is killed + terminationGracePeriodSeconds: 300 + # -- Affinity for overrides-exporter pods. + # @default -- Hard node anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: overrides-exporter + topologyKey: kubernetes.io/hostname + # -- Pod Disruption Budget maxUnavailable + maxUnavailable: null + # -- Node selector for overrides-exporter pods + nodeSelector: {} + # -- Topology Spread Constraints for overrides-exporter pods + topologySpreadConstraints: [] + # -- Tolerations for overrides-exporter pods + tolerations: [] + # -- Set the optional grpc service protocol. Ex: "grpc", "http2" or "https" + appProtocol: + grpc: "" + +memcached: + image: + # -- Memcached Docker image repository + repository: memcached + # -- Memcached Docker image tag + tag: 1.6.38-alpine + # -- Memcached Docker image pull policy + pullPolicy: IfNotPresent + # -- The SecurityContext override for memcached pods + podSecurityContext: + runAsNonRoot: true + runAsUser: 11211 + runAsGroup: 11211 + fsGroup: 11211 + # -- The name of the PriorityClass for memcached pods + priorityClassName: null + # -- The SecurityContext for memcached containers + containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: [ALL] + allowPrivilegeEscalation: false +memcachedExporter: + # -- Whether memcached metrics should be exported + enabled: true + image: + repository: prom/memcached-exporter + tag: v0.15.2 + pullPolicy: IfNotPresent + resources: + requests: {} + limits: {} + # -- The SecurityContext for memcached exporter containers + containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: [ALL] + allowPrivilegeEscalation: false + # -- Extra args to add to the exporter container. + # Example: + # extraArgs: + # memcached.tls.enable: true + # memcached.tls.cert-file: /certs/cert.crt + # memcached.tls.key-file: /certs/cert.key + # memcached.tls.ca-file: /certs/ca.crt + # memcached.tls.insecure-skip-verify: false + # memcached.tls.server-name: memcached + extraArgs: {} +resultsCache: + # -- Specifies whether memcached based results-cache should be enabled + enabled: true + # -- Specify how long cached results should be stored in the results-cache before being expired + defaultValidity: 12h + # -- Memcached operation timeout + timeout: 500ms + # -- Total number of results-cache replicas + replicas: 1 + # -- Port of the results-cache service + port: 11211 + # -- Amount of memory allocated to results-cache for object storage (in MB). + allocatedMemory: 1024 + # -- Maximum item results-cache for memcached (in MB). + maxItemMemory: 5 + # -- Maximum number of connections allowed + connectionLimit: 16384 + # -- Max memory to use for cache write back + writebackSizeLimit: 500MB + # -- Max number of objects to use for cache write back + writebackBuffer: 500000 + # -- Number of parallel threads for cache write back + writebackParallelism: 1 + # -- Extra init containers for results-cache pods + initContainers: [] + # -- Annotations for the results-cache pods + annotations: {} + # -- Node selector for results-cache pods + nodeSelector: {} + # -- Affinity for results-cache pods + affinity: {} + # -- topologySpreadConstraints allows to customize the default topologySpreadConstraints. This can be either a single dict as shown below or a slice of topologySpreadConstraints. + # labelSelector is taken from the constraint itself (if it exists) or is generated by the chart using the same selectors as for services. + topologySpreadConstraints: [] + # maxSkew: 1 + # topologyKey: kubernetes.io/hostname + # whenUnsatisfiable: ScheduleAnyway + # -- Tolerations for results-cache pods + tolerations: [] + # -- Pod Disruption Budget + podDisruptionBudget: + maxUnavailable: 1 + # -- The name of the PriorityClass for results-cache pods + priorityClassName: null + # -- Labels for results-cache pods + podLabels: {} + # -- Annotations for results-cache pods + podAnnotations: {} + # -- Management policy for results-cache pods + podManagementPolicy: Parallel + # -- Grace period to allow the results-cache to shutdown before it is killed + terminationGracePeriodSeconds: 60 + # -- Stateful results-cache strategy + statefulStrategy: + type: RollingUpdate + # -- Add extended options for results-cache memcached container. The format is the same as for the memcached -o/--extend flag. + # Example: + # extraExtendedOptions: 'tls,modern,track_sizes' + extraExtendedOptions: "" + # -- Additional CLI args for results-cache + extraArgs: {} + # -- Additional containers to be added to the results-cache pod. + extraContainers: [] + # -- Additional volumes to be added to the results-cache pod (applies to both memcached and exporter containers). + # Example: + # extraVolumes: + # - name: extra-volume + # secret: + # secretName: extra-volume-secret + extraVolumes: [] + # -- Additional volume mounts to be added to the results-cache pod (applies to both memcached and exporter containers). + # Example: + # extraVolumeMounts: + # - name: extra-volume + # mountPath: /etc/extra-volume + # readOnly: true + extraVolumeMounts: [] + # -- Resource requests and limits for the results-cache + # By default a safe memory limit will be requested based on allocatedMemory value (floor (* 1.2 allocatedMemory)). + resources: null + # -- Service annotations and labels + service: + annotations: {} + labels: {} + # -- Persistence settings for the results-cache + persistence: + # -- Enable creating PVCs for the results-cache + enabled: false + # -- Size of persistent disk, must be in G or Gi + storageSize: 10G + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Volume mount path + mountPath: /data +chunksCache: + # -- Specifies whether memcached based chunks-cache should be enabled + enabled: true + # -- Batchsize for sending and receiving chunks from chunks cache + batchSize: 4 + # -- Parallel threads for sending and receiving chunks from chunks cache + parallelism: 5 + # -- Memcached operation timeout + timeout: 2000ms + # -- Specify how long cached chunks should be stored in the chunks-cache before being expired + defaultValidity: 0s + # -- Total number of chunks-cache replicas + replicas: 1 + # -- Port of the chunks-cache service + port: 11211 + # -- Amount of memory allocated to chunks-cache for object storage (in MB). + allocatedMemory: 8192 + # -- Maximum item memory for chunks-cache (in MB). + maxItemMemory: 5 + # -- Maximum number of connections allowed + connectionLimit: 16384 + # -- Max memory to use for cache write back + writebackSizeLimit: 500MB + # -- Max number of objects to use for cache write back + writebackBuffer: 500000 + # -- Number of parallel threads for cache write back + writebackParallelism: 1 + # -- Extra init containers for chunks-cache pods + initContainers: [] + # -- Annotations for the chunks-cache pods + annotations: {} + # -- Node selector for chunks-cache pods + nodeSelector: {} + # -- Affinity for chunks-cache pods + affinity: {} + # -- topologySpreadConstraints allows to customize the default topologySpreadConstraints. This can be either a single dict as shown below or a slice of topologySpreadConstraints. + # labelSelector is taken from the constraint itself (if it exists) or is generated by the chart using the same selectors as for services. + topologySpreadConstraints: [] + # maxSkew: 1 + # topologyKey: kubernetes.io/hostname + # whenUnsatisfiable: ScheduleAnyway + # -- Tolerations for chunks-cache pods + tolerations: [] + # -- Pod Disruption Budget + podDisruptionBudget: + maxUnavailable: 1 + # -- The name of the PriorityClass for chunks-cache pods + priorityClassName: null + # -- Labels for chunks-cache pods + podLabels: {} + # -- Annotations for chunks-cache pods + podAnnotations: {} + # -- Management policy for chunks-cache pods + podManagementPolicy: Parallel + # -- Grace period to allow the chunks-cache to shutdown before it is killed + terminationGracePeriodSeconds: 60 + # -- Stateful chunks-cache strategy + statefulStrategy: + type: RollingUpdate + # -- Add extended options for chunks-cache memcached container. The format is the same as for the memcached -o/--extend flag. + # Example: + # extraExtendedOptions: 'tls,no_hashexpand' + extraExtendedOptions: "" + # -- Additional CLI args for chunks-cache + extraArgs: {} + # -- Additional containers to be added to the chunks-cache pod. + extraContainers: [] + # -- Additional volumes to be added to the chunks-cache pod (applies to both memcached and exporter containers). + # Example: + # extraVolumes: + # - name: extra-volume + # secret: + # secretName: extra-volume-secret + extraVolumes: [] + # -- Additional volume mounts to be added to the chunks-cache pod (applies to both memcached and exporter containers). + # Example: + # extraVolumeMounts: + # - name: extra-volume + # mountPath: /etc/extra-volume + # readOnly: true + extraVolumeMounts: [] + # -- Resource requests and limits for the chunks-cache + # By default a safe memory limit will be requested based on allocatedMemory value (floor (* 1.2 allocatedMemory)). + resources: null + # -- Service annotations and labels + service: + annotations: {} + labels: {} + # -- Persistence settings for the chunks-cache + persistence: + # -- Enable creating PVCs for the chunks-cache + enabled: false + # -- Size of persistent disk, must be in G or Gi + storageSize: 10G + # -- Storage class to be used. + # If defined, storageClassName: . + # If set to "-", storageClassName: "", which disables dynamic provisioning. + # If empty or set to null, no storageClassName spec is + # set, choosing the default provisioner (gp2 on AWS, standard on GKE, AWS, and OpenStack). + storageClass: null + # -- Volume mount path + mountPath: /data +###################################################################################################################### +# +# Subchart configurations +# +###################################################################################################################### +# -- Setting for the Grafana Rollout Operator https://github.com/grafana/helm-charts/tree/main/charts/rollout-operator +rollout_operator: + enabled: false + # -- podSecurityContext is the pod security context for the rollout operator. + # When installing on OpenShift, override podSecurityContext settings with + # + # rollout_operator: + # podSecurityContext: + # fsGroup: null + # runAsGroup: null + # runAsUser: null + podSecurityContext: + fsGroup: 10001 + runAsGroup: 10001 + runAsNonRoot: true + runAsUser: 10001 + seccompProfile: + type: RuntimeDefault + # Set the container security context + securityContext: + readOnlyRootFilesystem: true + capabilities: + drop: [ALL] + allowPrivilegeEscalation: false +# -- Configuration for the minio subchart +minio: + enabled: false + replicas: 1 + # Minio requires 2 to 16 drives for erasure code (drivesPerNode * replicas) + # https://docs.min.io/docs/minio-erasure-code-quickstart-guide + # Since we only have 1 replica, that means 2 drives must be used. + drivesPerNode: 2 + # root user; not used for GEL authentication + rootUser: root-user + rootPassword: supersecretpassword + # The first user in the list below is used for Loki/GEL authentication. + # You can add additional users if desired; they will not impact Loki/GEL. + # `accessKey` = username, `secretKey` = password + users: + - accessKey: logs-user + secretKey: supersecretpassword + policy: readwrite + buckets: + - name: chunks + policy: none + purge: false + - name: ruler + policy: none + purge: false + - name: admin + policy: none + purge: false + persistence: + size: 5Gi + annotations: {} + resources: + requests: + cpu: 100m + memory: 128Mi + # Allow the address used by Loki to refer to Minio to be overridden + address: null +# Create extra manifests via values. Would be passed through `tpl` for templating +# objects can also be provided as multiline strings, useful for templating field names +extraObjects: [] +# - apiVersion: v1 +# kind: ConfigMap +# metadata: +# name: loki-alerting-rules +# data: +# loki-alerting-rules.yaml: |- +# groups: +# - name: example +# rules: +# - alert: example +# expr: | +# sum(count_over_time({app="loki"} |~ "error")) > 0 +# for: 3m +# labels: +# severity: warning +# category: logs +# annotations: +# message: "loki has encountered errors" +# - | +# apiVersion: v1 +# kind: Secret +# type: Opaque +# metadata: +# name: loki-distributed-basic-auth +# data: +# {{- range .Values.loki.tenants }} +# {{ .name }}: {{ b64enc .password | quote }} +# {{- end }} + +sidecar: + image: + # -- The Docker registry and image for the k8s sidecar + repository: kiwigrid/k8s-sidecar + # -- Docker image tag + tag: 1.30.2 + # -- Docker image sha. If empty, no sha will be used + sha: "" + # -- Docker image pull policy + pullPolicy: IfNotPresent + # -- Resource requests and limits for the sidecar + resources: {} + # limits: + # cpu: 100m + # memory: 100Mi + # requests: + # cpu: 50m + # memory: 50Mi + # -- The SecurityContext for the sidecar. + securityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + # -- Set to true to skip tls verification for kube api calls. + skipTlsVerify: false + # -- Ensure that rule files aren't conflicting and being overwritten by prefixing their name with the namespace they are defined in. + enableUniqueFilenames: false + # -- Readiness probe definition. Probe is disabled on the sidecar by default. + readinessProbe: {} + # -- Liveness probe definition. Probe is disabled on the sidecar by default. + livenessProbe: {} + rules: + # -- Whether or not to create a sidecar to ingest rule from specific ConfigMaps and/or Secrets. + enabled: true + # -- Label that the configmaps/secrets with rules will be marked with. + label: loki_rule + # -- Label value that the configmaps/secrets with rules will be set to. + labelValue: "" + # -- Folder into which the rules will be placed. + folder: /rules + # -- Comma separated list of namespaces. If specified, the sidecar will search for config-maps/secrets inside these namespaces. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify 'ALL' to search in all namespaces. + searchNamespace: null + # -- Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH request, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # -- Search in configmap, secret, or both. + resource: both + # -- Absolute path to the shell script to execute after a configmap or secret has been reloaded. + script: null + # -- WatchServerTimeout: request to the server, asking it to cleanly close the connection after that. + # defaults to 60sec; much higher values like 3600 seconds (1h) are feasible for non-Azure K8S. + watchServerTimeout: 60 + # + # -- WatchClientTimeout: is a client-side timeout, configuring your local socket. + # If you have a network outage dropping all packets with no RST/FIN, + # this is how long your client waits before realizing & dropping the connection. + # Defaults to 66sec. + watchClientTimeout: 60 + # -- Log level of the sidecar container. + logLevel: INFO +############################################## WARNING ############################################################### +# +# DEPRECATED VALUES +# +# The following values are deprecated and will be removed in a future version of the helm chart! +# +############################################## WARNING ############################################################## + +# -- DEPRECATED Monitoring section determines which monitoring features to enable, this section is being replaced +# by https://github.com/grafana/meta-monitoring-chart +monitoring: + # Dashboards for monitoring Loki + dashboards: + # -- If enabled, create configmap with dashboards for monitoring Loki + enabled: false + # -- Alternative namespace to create dashboards ConfigMap in + namespace: null + # -- Additional annotations for the dashboards ConfigMap + annotations: {} + # -- Labels for the dashboards ConfigMap + labels: + grafana_dashboard: "1" + # -- DEPRECATED Recording rules for monitoring Loki, required for some dashboards + rules: + # -- If enabled, create PrometheusRule resource with Loki recording rules + enabled: false + # -- Include alerting rules + alerting: true + # -- Specify which individual alerts should be disabled + # -- Instead of turning off each alert one by one, set the .monitoring.rules.alerting value to false instead. + # -- If you disable all the alerts and keep .monitoring.rules.alerting set to true, the chart will fail to render. + disabled: {} + # LokiRequestErrors: true + # LokiRequestPanics: true + # -- Alternative namespace to create PrometheusRule resources in + namespace: null + # -- Additional annotations for the rules PrometheusRule resource + annotations: {} + # -- Additional labels for the rules PrometheusRule resource + labels: {} + # -- Additional labels for PrometheusRule alerts + additionalRuleLabels: {} + # -- Additional groups to add to the rules file + additionalGroups: [] + # - name: additional-loki-rules + # rules: + # - record: job:loki_request_duration_seconds_bucket:sum_rate + # expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job) + # - record: job_route:loki_request_duration_seconds_bucket:sum_rate + # expr: sum(rate(loki_request_duration_seconds_bucket[1m])) by (le, job, route) + # - record: node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate + # expr: sum(rate(container_cpu_usage_seconds_total[1m])) by (node, namespace, pod, container) + # -- DEPRECATED ServiceMonitor configuration + serviceMonitor: + # -- If enabled, ServiceMonitor resources for Prometheus Operator are created + enabled: false + # -- Namespace selector for ServiceMonitor resources + namespaceSelector: {} + # -- ServiceMonitor annotations + annotations: {} + # -- Additional ServiceMonitor labels + labels: {} + # -- ServiceMonitor scrape interval + # Default is 15s because included recording rules use a 1m rate, and scrape interval needs to be at + # least 1/4 rate interval. + interval: 15s + # -- ServiceMonitor scrape timeout in Go duration format (e.g. 15s) + scrapeTimeout: null + # -- ServiceMonitor relabel configs to apply to samples before scraping + # https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + relabelings: [] + # -- ServiceMonitor metric relabel configs to apply to samples before ingestion + # https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#endpoint + metricRelabelings: [] + # -- ServiceMonitor will use http by default, but you can pick https as well + scheme: http + # -- ServiceMonitor will use these tlsConfig settings to make the health check requests + tlsConfig: null + # -- If defined, will create a MetricsInstance for the Grafana Agent Operator. + metricsInstance: + # -- If enabled, MetricsInstance resources for Grafana Agent Operator are created + enabled: true + # -- MetricsInstance annotations + annotations: {} + # -- Additional MetricsInstance labels + labels: {} + # -- If defined a MetricsInstance will be created to remote write metrics. + remoteWrite: null + # -- DEPRECATED Self monitoring determines whether Loki should scrape its own logs. + # This feature currently relies on the Grafana Agent Operator being installed, + # which is installed by default using the grafana-agent-operator sub-chart. + # It will create custom resources for GrafanaAgent, LogsInstance, and PodLogs to configure + # scrape configs to scrape its own logs with the labels expected by the included dashboards. + selfMonitoring: + enabled: false + # -- Tenant to use for self monitoring + tenant: + # -- Name of the tenant + name: "self-monitoring" + # -- Password of the gateway for Basic auth + password: null + # -- Namespace to create additional tenant token secret in. Useful if your Grafana instance + # is in a separate namespace. Token will still be created in the canary namespace. + secretNamespace: "{{ .Release.Namespace }}" + # -- DEPRECATED Grafana Agent configuration + grafanaAgent: + # -- DEPRECATED Controls whether to install the Grafana Agent Operator and its CRDs. + # Note that helm will not install CRDs if this flag is enabled during an upgrade. + # In that case install the CRDs manually from https://github.com/grafana/agent/tree/main/production/operator/crds + installOperator: false + # -- Grafana Agent annotations + annotations: {} + # -- Additional Grafana Agent labels + labels: {} + # -- Enable the config read api on port 8080 of the agent + enableConfigReadAPI: false + # -- The name of the PriorityClass for GrafanaAgent pods + priorityClassName: null + # -- Resource requests and limits for the grafanaAgent pods + resources: {} + # limits: + # memory: 200Mi + # requests: + # cpu: 50m + # memory: 100Mi + # -- Tolerations for GrafanaAgent pods + tolerations: [] + # PodLogs configuration + podLogs: + # -- PodLogs version + apiVersion: monitoring.grafana.com/v1alpha1 + # -- PodLogs annotations + annotations: {} + # -- Additional PodLogs labels + labels: {} + # -- PodLogs relabel configs to apply to samples before scraping + # https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + relabelings: [] + # -- Additional pipeline stages to process logs after scraping + # https://grafana.com/docs/agent/latest/operator/api/#pipelinestagespec-a-namemonitoringgrafanacomv1alpha1pipelinestagespeca + additionalPipelineStages: [] + # LogsInstance configuration + logsInstance: + # -- LogsInstance annotations + annotations: {} + # -- Additional LogsInstance labels + labels: {} + # -- Additional clients for remote write + clients: null +# -- DEPRECATED Configuration for the table-manager. The table-manager is only necessary when using a deprecated +# index type such as Cassandra, Bigtable, or DynamoDB, it has not been necessary since loki introduced self- +# contained index types like 'boltdb-shipper' and 'tsdb'. This will be removed in a future helm chart. +tableManager: + # -- Specifies whether the table-manager should be enabled + enabled: false + image: + # -- The Docker registry for the table-manager image. Overrides `loki.image.registry` + registry: null + # -- Docker image repository for the table-manager image. Overrides `loki.image.repository` + repository: null + # -- Docker image tag for the table-manager image. Overrides `loki.image.tag` + tag: null + # -- Command to execute instead of defined in Docker image + command: null + # -- The name of the PriorityClass for table-manager pods + priorityClassName: null + # -- Labels for table-manager pods + podLabels: {} + # -- Annotations for table-manager deployment + annotations: {} + # -- Annotations for table-manager pods + podAnnotations: {} + service: + # -- Annotations for table-manager Service + annotations: {} + # -- Additional labels for table-manager Service + labels: {} + # -- Additional CLI args for the table-manager + extraArgs: [] + # -- Environment variables to add to the table-manager pods + extraEnv: [] + # -- Environment variables from secrets or configmaps to add to the table-manager pods + extraEnvFrom: [] + # -- Volume mounts to add to the table-manager pods + extraVolumeMounts: [] + # -- Volumes to add to the table-manager pods + extraVolumes: [] + # -- Resource requests and limits for the table-manager + resources: {} + # -- Containers to add to the table-manager pods + extraContainers: [] + # -- Grace period to allow the table-manager to shutdown before it is killed + terminationGracePeriodSeconds: 30 + # -- Affinity for table-manager pods. + # @default -- Hard node and anti-affinity + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/component: table-manager + topologyKey: kubernetes.io/hostname + # -- DNS config table-manager pods + dnsConfig: {} + # -- Node selector for table-manager pods + nodeSelector: {} + # -- Tolerations for table-manager pods + tolerations: [] + # -- Enable deletes by retention + retention_deletes_enabled: false + # -- Set retention period + retention_period: 0 diff --git a/charts/mayastor/charts/nats/.helmignore b/charts/mayastor/charts/nats/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/charts/mayastor/charts/nats/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/mayastor/charts/nats/Chart.yaml b/charts/mayastor/charts/nats/Chart.yaml new file mode 100644 index 0000000..0a2626c --- /dev/null +++ b/charts/mayastor/charts/nats/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v2 +appVersion: 2.9.17 +description: A Helm chart for the NATS.io High Speed Cloud Native Distributed Communications + Technology. +home: http://github.com/nats-io/k8s +icon: https://nats.io/img/nats-icon-color.png +keywords: +- nats +- messaging +- cncf +maintainers: +- email: info@nats.io + name: The NATS Authors + url: https://github.com/nats-io +name: nats +version: 0.19.14 diff --git a/charts/mayastor/charts/nats/README.md b/charts/mayastor/charts/nats/README.md new file mode 100644 index 0000000..5c8aed2 --- /dev/null +++ b/charts/mayastor/charts/nats/README.md @@ -0,0 +1,918 @@ +# NATS Server + +[NATS](https://nats.io) is a simple, secure and performant communications system for digital systems, services and devices. NATS is part of the Cloud Native Computing Foundation ([CNCF](https://cncf.io)). NATS has over [30 client language implementations](https://nats.io/download/), and its server can run on-premise, in the cloud, at the edge, and even on a Raspberry Pi. NATS can secure and simplify design and operation of modern distributed systems. + +## TL;DR; + +```console +helm repo add nats https://nats-io.github.io/k8s/helm/charts/ +helm install my-nats nats/nats +``` + +## Breaking Change Log + +- **0.15.0**: For users with JetStream enabled (`nats.jetstream.enabled = true`): `nats.jetstream.fileStorage.enabled` now defaults to `true` and `nats.jetstream.fileStorage.size` now defaults to `10Gi`. This updates the StatefulSet `spec.volumeClaimTemplates` field, which is immutable and cannot be changed on an existing StatefulSet; to upgrade from an older chart version, add the value: + ```yaml + nats: + jetstream: + fileStorage: + # add if enabled was previously the default setting + # not recommended; it would be better to migrate to a StatefulSet with storage enabled + enabled: false + # add if size was previously the default setting + size: 1Gi + ``` +- **0.12.0**: The `podManagementPolicy` value was introduced and set to `Parallel` by default, which controls the StatefulSet `spec.podManagementPolicy` field. This field is immutable and cannot be changed on an existing StatefulSet; to upgrade from an older chart version, add the value: + ```yaml + podManagementPolicy: OrderedReady + ``` + +## Configuration + +### Server Image + +```yaml +# use a specific versions +nats: + image: + tag: X.Y.Z-alpine + +# fully custom location +nats: + image: + registry: my.custom.registry + repository: my-nats + tag: latest + pullPolicy: Always +``` + +### Limits + +```yaml +nats: + # The number of connect attempts against discovered routes. + connectRetries: 30 + + # How many seconds should pass before sending a PING + # to a client that has no activity. + pingInterval: + + # Server settings. + limits: + maxConnections: + maxSubscriptions: + maxControlLine: + maxPayload: + + writeDeadline: + maxPending: + maxPings: + lameDuckDuration: + + # Number of seconds to wait for client connections to end after the pod termination is requested + terminationGracePeriodSeconds: 60 +``` + +#### Setting Go Memory Limit (Recommended) + +Since NATS Server v2.9 release, it is possible to use the `GOMEMLIMIT` environment variable to signal memory limits to the Go runtime (which is by default unaware of cgroups memory limits). You should set this to about 90% of the intended available memory resources for the NATS Server container. + +```yaml +nats: + gomemlimit: "4GiB" +``` + +### Logging + +*Note*: It is not recommended to enable trace or debug in production since enabling it will significantly degrade performance. + +```yaml +nats: + logging: + debug: + trace: + logtime: + connectErrorReports: + reconnectErrorReports: +``` + +### TLS setup for client connections + +You can find more on how to setup and trouble shoot TLS connnections at: +https://docs.nats.io/nats-server/configuration/securing_nats/tls + +```yaml +nats: + tls: + secret: + name: nats-client-tls + ca: "ca.crt" + cert: "tls.crt" + key: "tls.key" +``` + +## Clustering + +If clustering is enabled, then a 3-node cluster will be setup. More info at: +https://docs.nats.io/nats-server/configuration/clustering#nats-server-clustering + +```yaml +cluster: + enabled: true + replicas: 3 + + tls: + secret: + name: nats-server-tls + ca: "ca.crt" + cert: "tls.crt" + key: "tls.key" +``` + +Example: + +```sh +$ helm install nats nats/nats --set cluster.enabled=true +``` + +## Leafnodes + +Leafnode connections to extend a cluster. More info at: +https://docs.nats.io/nats-server/configuration/leafnodes + +```yaml +leafnodes: + enabled: true + remotes: + - url: "tls://connect.ngs.global:7422" + # credentials: + # secret: + # name: leafnode-creds + # key: TA.creds + # tls: + # secret: + # name: nats-leafnode-tls + # ca: "ca.crt" + # cert: "tls.crt" + # key: "tls.key" + + ####################### + # # + # TLS Configuration # + # # + ####################### + # + # # You can find more on how to setup and trouble shoot TLS connnections at: + # + # # https://docs.nats.io/nats-server/configuration/securing_nats/tls + # + tls: + secret: + name: nats-client-tls + ca: "ca.crt" + cert: "tls.crt" + key: "tls.key" +``` + +## Setting up External Access + +### Using HostPorts + +In case of both external access and advertisements being enabled, an +initializer container will be used to gather the public ips. This +container will required to have enough RBAC policy to be able to make a +look up of the public ip of the node where it is running. + +For example, to setup external access for a cluster and advertise the public ip to clients: + +```yaml +nats: + # Toggle whether to enable external access. + # This binds a host port for clients, gateways and leafnodes. + externalAccess: true + + # Toggle to disable client advertisements (connect_urls), + # in case of running behind a load balancer + # it might be required to disable advertisements. + advertise: true + + # In case both external access and advertise are enabled + # then a service account would be required to be able to + # gather the public ip from a node. + serviceAccount: "nats-server" +``` + +Where the service account named `nats-server` has the following RBAC policy for example: + +```yaml +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: nats-server + namespace: default +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: nats-server +rules: +- apiGroups: [""] + resources: + - nodes + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: nats-server-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: nats-server +subjects: +- kind: ServiceAccount + name: nats-server + namespace: default +``` + +The container image of the initializer can be customized via: + +```yaml +bootconfig: + image: + tag: X.Y.Z +``` + +### Using LoadBalancers + +In case of using a load balancer for external access, it is recommended to disable no advertise +so that internal ips from the NATS Servers are not advertised to the clients connecting through +the load balancer. + +```yaml +cluster: + enabled: true + noAdvertise: true + +leafnodes: + enabled: true + noAdvertise: true + +natsbox: + enabled: true +``` + +Then could use an L4 enabled load balancer to connect to NATS, for example: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: nats-lb +spec: + type: LoadBalancer + selector: + app.kubernetes.io/name: nats + ports: + - protocol: TCP + port: 4222 + targetPort: 4222 + name: nats + - protocol: TCP + port: 7422 + targetPort: 7422 + name: leafnodes + - protocol: TCP + port: 7522 + targetPort: 7522 + name: gateways +``` + +### Using NATS Chart as a Dependency + +In order to fully manage your deployment through Helm, you can use `nats` as a [helm dependency](https://helm.sh/docs/helm/helm_dependency/#helm-dependency). This is our recommend approach for exposing your NATS deployment with Services or WebSocket Ingresses. + +1. Example uses a helm chart named `mynats` (example: `helm create mynats`) +2. In `Chart.yaml` add the following dependencies block + ```yaml + dependencies: + - name: nats + version: 0.18.0 + repository: https://nats-io.github.io/k8s/helm/charts/ + ``` +3. Run `helm dep update` now (and any time you update the `nats` dependency version) +4. Add `nats` settings to the `values.yaml` file: + ```yaml + # notice the extra nats key here, must match the dependency name in Chart.yaml + nats: + nats: + jetstream: + enabled: true + cluster: + enabled: true + # disable cluster advertisements when running behind a load balancer + noAdvertise: true + + # add whatever other nats settings you need here + ``` +5. Add a template for your service to `templates/service-lb.yaml`: + ```yaml + apiVersion: v1 + kind: Service + metadata: + name: {{ include "mynats.fullname" . }}-lb + labels: + {{- include "mynats.labels" . | nindent 4 }} + spec: + type: LoadBalancer + selector: + {{- include "nats.selectorLabels" .Subcharts.nats | nindent 4 }} + ports: + - name: nats + port: 4222 + protocol: TCP + targetPort: 4222 + ``` + +## Gateways + +A super cluster can be formed by pointing to remote gateways. +You can find more about gateways in the NATS documentation: +https://docs.nats.io/nats-server/configuration/gateways + +> ⚠️ Note: When using Gateways and JetStream make sure that the deployment name is different so that the generated server names do not collide. + +```yaml +gateway: + enabled: false + name: 'default' + + ############################# + # # + # List of remote gateways # + # # + ############################# + # gateways: + # - name: other + # url: nats://my-gateway-url:7522 + + ####################### + # # + # TLS Configuration # + # # + ####################### + # + # # You can find more on how to setup and trouble shoot TLS connnections at: + # + # # https://docs.nats.io/nats-server/configuration/securing_nats/tls + # + # tls: + # secret: + # name: nats-client-tls + # ca: "ca.crt" + # cert: "tls.crt" + # key: "tls.key" +``` + +## Auth setup + +### Auth with a Memory Resolver + +```yaml +auth: + enabled: true + + # Reference to the Operator JWT. + operatorjwt: + configMap: + name: operator-jwt + key: KO.jwt + + # Public key of the System Account + systemAccount: + + resolver: + ############################ + # # + # Memory resolver settings # + # # + ############################## + type: memory + + # + # Use a configmap reference which will be mounted + # into the container. + # + configMap: + name: nats-accounts + key: resolver.conf +``` + +### Auth using an Account Server Resolver + +```yaml +auth: + enabled: true + + # Reference to the Operator JWT. + operatorjwt: + configMap: + name: operator-jwt + key: KO.jwt + + # Public key of the System Account + systemAccount: + + resolver: + ########################## + # # + # URL resolver settings # + # # + ########################## + type: URL + url: "http://nats-account-server:9090/jwt/v1/accounts/" +``` + +## JetStream + +### Setting up Memory and File Storage + +File Storage is **always** recommended, since JetStream's RAFT Meta Group will be persisted to file storage. The Storage Class used should be block storage. NFS is not recommended. + +```yaml +nats: + jetstream: + enabled: true + + memStorage: + enabled: true + size: 2Gi + + fileStorage: + enabled: true + size: 10Gi + # storageClassName: gp2 # NOTE: AWS setup but customize as needed for your infra. +``` + +### Using with an existing PersistentVolumeClaim + +For example, given the following `PersistentVolumeClaim`: + +```yaml +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: nats-js-disk + annotations: + volume.beta.kubernetes.io/storage-class: "default" +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi +``` + +You can start JetStream so that one pod is bounded to it: + +```yaml +nats: + jetstream: + enabled: true + + fileStorage: + enabled: true + storageDirectory: /data/ + existingClaim: nats-js-disk + claimStorageSize: 3Gi +``` + +### Clustering example + +```yaml + +nats: + jetstream: + enabled: true + + memStorage: + enabled: true + size: "2Gi" + + fileStorage: + enabled: true + size: "10Gi" + +cluster: + enabled: true + # Cluster name is required, by default will be release name. + # name: "nats" + replicas: 3 +``` + +### Basic Authentication and JetStream + +```yaml +nats: + jetstream: + enabled: true + + memStorage: + enabled: true + size: "2Gi" + + fileStorage: + enabled: true + size: "10Gi" + # storageClassName: gp2 # NOTE: AWS setup but customize as needed for your infra. + +cluster: + enabled: true + # Can set a custom cluster name + # name: "nats" + replicas: 3 + +auth: + enabled: true + + systemAccount: "$SYS" + + basic: + accounts: + $SYS: + users: + - user: sys + pass: sys + js: + jetstream: true + users: + - user: foo +``` + +### NATS Resolver setup example + +As of NATS v2.2, the server now has a built-in NATS resolver of accounts. +The following is an example guide of how to get it configured. + +```sh +# Create a working directory to keep the creds. +mkdir nats-creds +cd nats-creds + +# This just creates some accounts for you to get started. +curl -fSl https://nats-io.github.io/k8s/setup/nsc-setup.sh | sh +source .nsc.env + +# You should have some accounts now, at least the following. +nsc list accounts ++-------------------------------------------------------------------+ +| Accounts | ++--------+----------------------------------------------------------+ +| Name | Public Key | ++--------+----------------------------------------------------------+ +| A | ABJ4OIKBBFCNXZDP25C7EWXCXOVCYYAGBEHFAG7F5XYCOYPHZLNSJYDF | +| B | ACVRK7GFBRQUCB3NEABGQ7XPNED2BSPT27GOX5QBDYW2NOFMQKK755DJ | +| SYS | ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N | ++--------+----------------------------------------------------------+ + +# Now create an account with JetStream support +export account=JS1 +nsc add account --name $account +nsc edit account --name $account --js-disk-storage -1 --js-consumer -1 --js-streams -1 +nsc add user -a $account js-user +``` + +Next, generate the NATS resolver config. This will be used to fill in the values of the YAML in the Helm template. +For example the result of generating this: + +```sh +nsc generate config --sys-account SYS --nats-resolver + +# Operator named KO +operator: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJDRlozRlE0WURNTUc1Q1UzU0FUWVlHWUdQUDJaQU1QUzVNRUdNWFdWTUJFWUdIVzc2WEdBIiwiaWF0IjoxNjMyNzgzMDk2LCJpc3MiOiJPQ0lWMlFGSldJTlpVQVQ1VDJZSkJJUkMzQjZKS01TWktRTkY1S0dQNE4zS1o0RkZEVkFXWVhDTCIsIm5hbWUiOiJLTyIsInN1YiI6Ik9DSVYyUUZKV0lOWlVBVDVUMllKQklSQzNCNkpLTVNaS1FORjVLR1A0TjNLWjRGRkRWQVdZWENMIiwibmF0cyI6eyJ0eXBlIjoib3BlcmF0b3IiLCJ2ZXJzaW9uIjoyfX0.e3gvJ-C1IBznmbUljeT_wbLRl1akv5IGBS3rbxs6mzzTvf3zlqQI4wDKVE8Gvb8qfTX6TIwocClfOqNaN3k3CQ + +# System Account named SYS +system_account: ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N + +resolver_preload: { + ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJDR0tWVzJGQUszUE5XQTRBWkhHT083UTdZWUVPQkJYNDZaTU1VSFc1TU5QSUFVSFE0RVRRIiwiaWF0IjoxNjMyNzgzMDk2LCJpc3MiOiJPQ0lWMlFGSldJTlpVQVQ1VDJZSkJJUkMzQjZKS01TWktRTkY1S0dQNE4zS1o0RkZEVkFXWVhDTCIsIm5hbWUiOiJTWVMiLCJzdWIiOiJBREdGSDROWVY1Vjc1U1ZNNURZU1c1QVdPRDdIMk5SVVdBTU82WExaS0lER1VXWUVYQ1pHNUQ2TiIsIm5hdHMiOnsibGltaXRzIjp7InN1YnMiOi0xLCJkYXRhIjotMSwicGF5bG9hZCI6LTEsImltcG9ydHMiOi0xLCJleHBvcnRzIjotMSwid2lsZGNhcmRzIjp0cnVlLCJjb25uIjotMSwibGVhZiI6LTF9LCJkZWZhdWx0X3Blcm1pc3Npb25zIjp7InB1YiI6e30sInN1YiI6e319LCJ0eXBlIjoiYWNjb3VudCIsInZlcnNpb24iOjJ9fQ.J7g73TEn-ZT13owq4cVWl4l0hZnGK4DJtH2WWOZmGbefcCQ1xsx4cIagKc1cZTCwUpELVAYnSkmPp4LsQOspBg, +} +``` + +In the YAML would be configured as follows: + +``` +auth: + enabled: true + + timeout: "5s" + + resolver: + type: full + + operator: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJDRlozRlE0WURNTUc1Q1UzU0FUWVlHWUdQUDJaQU1QUzVNRUdNWFdWTUJFWUdIVzc2WEdBIiwiaWF0IjoxNjMyNzgzMDk2LCJpc3MiOiJPQ0lWMlFGSldJTlpVQVQ1VDJZSkJJUkMzQjZKS01TWktRTkY1S0dQNE4zS1o0RkZEVkFXWVhDTCIsIm5hbWUiOiJLTyIsInN1YiI6Ik9DSVYyUUZKV0lOWlVBVDVUMllKQklSQzNCNkpLTVNaS1FORjVLR1A0TjNLWjRGRkRWQVdZWENMIiwibmF0cyI6eyJ0eXBlIjoib3BlcmF0b3IiLCJ2ZXJzaW9uIjoyfX0.e3gvJ-C1IBznmbUljeT_wbLRl1akv5IGBS3rbxs6mzzTvf3zlqQI4wDKVE8Gvb8qfTX6TIwocClfOqNaN3k3CQ + + systemAccount: ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N + + store: + dir: "/etc/nats-config/accounts/jwt" + size: "1Gi" + + resolverPreload: + ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJDR0tWVzJGQUszUE5XQTRBWkhHT083UTdZWUVPQkJYNDZaTU1VSFc1TU5QSUFVSFE0RVRRIiwiaWF0IjoxNjMyNzgzMDk2LCJpc3MiOiJPQ0lWMlFGSldJTlpVQVQ1VDJZSkJJUkMzQjZKS01TWktRTkY1S0dQNE4zS1o0RkZEVkFXWVhDTCIsIm5hbWUiOiJTWVMiLCJzdWIiOiJBREdGSDROWVY1Vjc1U1ZNNURZU1c1QVdPRDdIMk5SVVdBTU82WExaS0lER1VXWUVYQ1pHNUQ2TiIsIm5hdHMiOnsibGltaXRzIjp7InN1YnMiOi0xLCJkYXRhIjotMSwicGF5bG9hZCI6LTEsImltcG9ydHMiOi0xLCJleHBvcnRzIjotMSwid2lsZGNhcmRzIjp0cnVlLCJjb25uIjotMSwibGVhZiI6LTF9LCJkZWZhdWx0X3Blcm1pc3Npb25zIjp7InB1YiI6e30sInN1YiI6e319LCJ0eXBlIjoiYWNjb3VudCIsInZlcnNpb24iOjJ9fQ.J7g73TEn-ZT13owq4cVWl4l0hZnGK4DJtH2WWOZmGbefcCQ1xsx4cIagKc1cZTCwUpELVAYnSkmPp4LsQOspBg +``` + +Now we start the server with the NATS Account Resolver (`auth.resolver.type=full`): + +```yaml +nats: + logging: + debug: false + trace: false + + jetstream: + enabled: true + + memStorage: + enabled: true + size: "2Gi" + + fileStorage: + enabled: true + size: "10Gi" + # storageClassName: gp2 # NOTE: AWS setup but customize as needed for your infra. + +cluster: + enabled: true + # Can set a custom cluster name + name: "nats" + replicas: 3 + +auth: + enabled: true + + timeout: "5s" + + resolver: + type: full + + operator: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJDRlozRlE0WURNTUc1Q1UzU0FUWVlHWUdQUDJaQU1QUzVNRUdNWFdWTUJFWUdIVzc2WEdBIiwiaWF0IjoxNjMyNzgzMDk2LCJpc3MiOiJPQ0lWMlFGSldJTlpVQVQ1VDJZSkJJUkMzQjZKS01TWktRTkY1S0dQNE4zS1o0RkZEVkFXWVhDTCIsIm5hbWUiOiJLTyIsInN1YiI6Ik9DSVYyUUZKV0lOWlVBVDVUMllKQklSQzNCNkpLTVNaS1FORjVLR1A0TjNLWjRGRkRWQVdZWENMIiwibmF0cyI6eyJ0eXBlIjoib3BlcmF0b3IiLCJ2ZXJzaW9uIjoyfX0.e3gvJ-C1IBznmbUljeT_wbLRl1akv5IGBS3rbxs6mzzTvf3zlqQI4wDKVE8Gvb8qfTX6TIwocClfOqNaN3k3CQ + + systemAccount: ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N + + store: + dir: "/etc/nats-config/accounts/jwt" + size: "1Gi" + + resolverPreload: + ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJDR0tWVzJGQUszUE5XQTRBWkhHT083UTdZWUVPQkJYNDZaTU1VSFc1TU5QSUFVSFE0RVRRIiwiaWF0IjoxNjMyNzgzMDk2LCJpc3MiOiJPQ0lWMlFGSldJTlpVQVQ1VDJZSkJJUkMzQjZKS01TWktRTkY1S0dQNE4zS1o0RkZEVkFXWVhDTCIsIm5hbWUiOiJTWVMiLCJzdWIiOiJBREdGSDROWVY1Vjc1U1ZNNURZU1c1QVdPRDdIMk5SVVdBTU82WExaS0lER1VXWUVYQ1pHNUQ2TiIsIm5hdHMiOnsibGltaXRzIjp7InN1YnMiOi0xLCJkYXRhIjotMSwicGF5bG9hZCI6LTEsImltcG9ydHMiOi0xLCJleHBvcnRzIjotMSwid2lsZGNhcmRzIjp0cnVlLCJjb25uIjotMSwibGVhZiI6LTF9LCJkZWZhdWx0X3Blcm1pc3Npb25zIjp7InB1YiI6e30sInN1YiI6e319LCJ0eXBlIjoiYWNjb3VudCIsInZlcnNpb24iOjJ9fQ.J7g73TEn-ZT13owq4cVWl4l0hZnGK4DJtH2WWOZmGbefcCQ1xsx4cIagKc1cZTCwUpELVAYnSkmPp4LsQOspBg +``` + +Finally, using a local port-forward make it possible to establish a connection to one of the servers and upload the accounts. + +```sh +nsc push --system-account SYS -u nats://localhost:4222 -A +[ OK ] push to nats-server "nats://localhost:4222" using system account "SYS": + [ OK ] push JS1 to nats-server with nats account resolver: + [ OK ] pushed "JS1" to nats-server nats-0: jwt updated + [ OK ] pushed "JS1" to nats-server nats-1: jwt updated + [ OK ] pushed "JS1" to nats-server nats-2: jwt updated + [ OK ] pushed to a total of 3 nats-server +``` + +Now you should be able to use JetStream and the NATS based account resolver: + +```sh +nats stream ls -s localhost --creds ./nsc/nkeys/creds/KO/JS1/js-user.creds +No Streams defined +``` + +## Misc + +### NATS Box + +A lightweight container with NATS and NATS Streaming utilities that is deployed along the cluster to confirm the setup. +You can find the image at: https://github.com/nats-io/nats-box + +```yaml +natsbox: + enabled: true + image: + tag: X.Y.Z + + # credentials: + # secret: + # name: nats-sys-creds + # key: sys.creds +``` + +You can also add volumes to nats-box, for example given a PVC like: + +```yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: nsc-pvc +spec: + accessModes: + - ReadWriteOnce + volumeMode: Filesystem + resources: + requests: + storage: 1Gi +``` + +You can give state to nats-box by using the `extraVolumes` and `extraVolumeMounts` options: + +```yaml +natsbox: + enabled: true + extraVolumes: + - name: nsc + persistentVolumeClaim: + claimName: nsc-pvc + extraVolumeMounts: + - mountPath: /nsc + name: nsc +``` + +example: + +```sh +$ helm install nats-nsc nats/nats -f examples/nats-box-persistent.yaml +$ kubectl exec -it deployment/nats-nsc-box -- /bin/sh + +# cd /nsc +/nsc # curl -fSl https://nats-io.github.io/k8s/setup/nsc-setup.sh | sh +/nsc # source .nsc.env +/nsc # nsc list accounts +``` + +### Configuration Checksum + +A configuration checksum annotation is enabled by default on StatefulSet Pods in order to force a rollout when the NATS configuration changes. This checksum is only applied by `helm` commands, and will not change if configuration is modified outside of setting `helm` values. + +```yaml +nats: + configChecksumAnnotation: true +``` + +### Configuration Reload sidecar + +The NATS configuration reload sidecar is enabled by default; it passes the configuration reload signal to the NATS server when it detects configuration changes: + +```yaml +reloader: + enabled: true + image: + tag: X.Y.Z +``` + +### Prometheus Exporter sidecar + +The Prometheus Exporter sidecar is enabled by default; it can be used to feed metrics to Prometheus: + +```yaml +exporter: + enabled: true + image: + tag: X.Y.Z +``` + +### Prometheus operator ServiceMonitor support + +You can enable prometheus operator ServiceMonitor: + +```yaml +exporter: + # You have to enable exporter first + enabled: true + serviceMonitor: + enabled: true + ## Specify the namespace where Prometheus Operator is running + # namespace: monitoring + # ... +``` + +### Pod Customizations + +#### Security Context + +```yaml + # Toggle whether to use setup a Pod Security Context + # ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +securityContext: + fsGroup: 1000 + runAsUser: 1000 + runAsNonRoot: true +``` + +#### Affinity + + + +`matchExpressions` must be configured according to your setup + +```yaml +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node.kubernetes.io/purpose + operator: In + values: + - nats + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - nats + - stan + topologyKey: "kubernetes.io/hostname" +``` + +#### Service topology + +[Service topology](https://kubernetes.io/docs/concepts/services-networking/service-topology/) is disabled by default, but can be enabled by setting `topologyKeys`. For example: + +```yaml +topologyKeys: + - "kubernetes.io/hostname" + - "topology.kubernetes.io/zone" + - "topology.kubernetes.io/region" +``` + +#### CPU/Memory Resource Requests/Limits +Sets the pods cpu/memory requests/limits + +```yaml +nats: + resources: + requests: + cpu: 4 + memory: 8Gi + limits: + cpu: 6 + memory: 10Gi +``` + +No resources are set by default. It is recommended for NATS JetStream deployments to allocate at least 8Gi of memory and 4 cpus. + +#### Annotations + + + +```yaml +podAnnotations: + key1 : "value1", + key2 : "value2" +``` + +### Name Overides + +Can change the name of the resources as needed with: + +```yaml +nameOverride: "my-nats" +``` + +### Image Pull Secrets + +```yaml +imagePullSecrets: +- name: myRegistry +``` + +Adds this to the StatefulSet: + +```yaml +spec: + imagePullSecrets: + - name: myRegistry +``` + +### Mixed TLS and non TLS mode + +You can use the `nats.tls.allowNonTLS` option to allow a cluster to use TLS connections +and plain connections: + +```yaml +nats: + client: + port: 4222 + + tls: + allowNonTLS: true + secret: + name: nats-server-tls + ca: "ca.crt" + cert: "tls.crt" + key: "tls.key" + timeout: "5s" +``` diff --git a/charts/mayastor/charts/nats/templates/NOTES.txt b/charts/mayastor/charts/nats/templates/NOTES.txt new file mode 100644 index 0000000..694dc67 --- /dev/null +++ b/charts/mayastor/charts/nats/templates/NOTES.txt @@ -0,0 +1,26 @@ + +{{- if or .Values.nats.logging.debug .Values.nats.logging.trace }} +*WARNING*: Keep in mind that running the server with +debug and/or trace enabled significantly affects the +performance of the server! +{{- end }} + +You can find more information about running NATS on Kubernetes +in the NATS documentation website: + + https://docs.nats.io/nats-on-kubernetes/nats-kubernetes + +{{- if .Values.natsbox.enabled }} + +NATS Box has been deployed into your cluster, you can +now use the NATS tools within the container as follows: + + kubectl exec -n {{ template "nats.namespace" . }} -it deployment/{{ template "nats.fullname" . }}-box -- /bin/sh -l + + nats-box:~# nats sub test & + nats-box:~# nats pub test hi + nats-box:~# nc {{ template "nats.fullname" . }} {{ .Values.nats.client.port }} + +{{- end }} + +Thanks for using NATS! diff --git a/charts/mayastor/charts/nats/templates/_helpers.tpl b/charts/mayastor/charts/nats/templates/_helpers.tpl new file mode 100644 index 0000000..9f177b8 --- /dev/null +++ b/charts/mayastor/charts/nats/templates/_helpers.tpl @@ -0,0 +1,256 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "nats.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "nats.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{- define "nats.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "nats.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "nats.labels" -}} +helm.sh/chart: {{ include "nats.chart" . }} +{{- range $name, $value := .Values.commonLabels }} +{{ $name }}: {{ tpl $value $ }} +{{- end }} +{{ include "nats.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "nats.selectorLabels" -}} +{{- if .Values.nats.selectorLabels }} +{{ tpl (toYaml .Values.nats.selectorLabels) . }} +{{- else -}} +app.kubernetes.io/name: {{ include "nats.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{- end }} + + +{{/* +Return the proper NATS image name +*/}} +{{- define "nats.clusterAdvertise" -}} +{{- if $.Values.useFQDN }} +{{- printf "$(POD_NAME).%s.$(POD_NAMESPACE).svc.%s" (include "nats.fullname" . ) $.Values.k8sClusterDomain }} +{{- else }} +{{- printf "$(POD_NAME).%s.$(POD_NAMESPACE)" (include "nats.fullname" . ) }} +{{- end }} +{{- end }} + +{{/* +Return the NATS cluster auth. +*/}} +{{- define "nats.clusterAuth" -}} +{{- if $.Values.cluster.authorization }} +{{- printf "%s:%s@" (urlquery $.Values.cluster.authorization.user) (urlquery $.Values.cluster.authorization.password) -}} +{{- else }} +{{- end }} +{{- end }} + +{{/* +Return the NATS cluster routes. +*/}} +{{- define "nats.clusterRoutes" -}} +{{- $name := (include "nats.fullname" . ) -}} +{{- $namespace := (include "nats.namespace" . ) -}} +{{- $clusterAuth := (include "nats.clusterAuth" . ) -}} +{{- range $i, $e := until (.Values.cluster.replicas | int) -}} +{{- if $.Values.useFQDN }} +{{- printf "nats://%s%s-%d.%s.%s.svc.%s:6222," $clusterAuth $name $i $name $namespace $.Values.k8sClusterDomain -}} +{{- else }} +{{- printf "nats://%s%s-%d.%s.%s:6222," $clusterAuth $name $i $name $namespace -}} +{{- end }} +{{- end -}} +{{- end }} + +{{- define "nats.extraRoutes" -}} +{{- range $i, $url := .Values.cluster.extraRoutes -}} +{{- printf "%s," $url -}} +{{- end -}} +{{- end }} + +{{- define "nats.tlsConfig" -}} +tls { +{{- if .cert }} + cert_file: {{ .secretPath }}/{{ .secret.name }}/{{ .cert }} +{{- end }} +{{- if .key }} + key_file: {{ .secretPath }}/{{ .secret.name }}/{{ .key }} +{{- end }} +{{- if .ca }} + ca_file: {{ .secretPath }}/{{ .secret.name }}/{{ .ca }} +{{- end }} +{{- if .insecure }} + insecure: {{ .insecure }} +{{- end }} +{{- if .verify }} + verify: {{ .verify }} +{{- end }} +{{- if .verifyAndMap }} + verify_and_map: {{ .verifyAndMap }} +{{- end }} +{{- if .verifyCertAndCheckKnownUrls }} + verify_cert_and_check_known_urls: {{ .verifyCertAndCheckKnownUrls }} +{{- end }} +{{- if .curvePreferences }} + curve_preferences: {{ .curvePreferences }} +{{- end }} +{{- if .timeout }} + timeout: {{ .timeout }} +{{- end }} +{{- if .cipherSuites }} + cipher_suites: {{ toRawJson .cipherSuites }} +{{- end }} +} +{{- end }} + +{{- define "nats.tlsReloaderArgs" -}} +{{ $secretName := .secret.name }} +{{ $secretPath := .secretPath }} +{{- with .ca }} +- -config +- {{ $secretPath }}/{{ $secretName }}/{{ . }} +{{- end }} +{{- with .cert }} +- -config +- {{ $secretPath }}/{{ $secretName }}/{{ . }} +{{- end }} +{{- with .key }} +- -config +- {{ $secretPath }}/{{ $secretName }}/{{ . }} +{{- end }} +{{- end }} + +{{- define "nats.tlsVolumeMounts" -}} +{{- with .Values.nats.tls }} +####################### +# # +# TLS Volumes Mounts # +# # +####################### +{{ $secretName := tpl .secret.name $ }} +- name: {{ $secretName }}-clients-volume + mountPath: /etc/nats-certs/clients/{{ $secretName }} +{{- end }} +{{- with .Values.mqtt.tls }} +{{ $secretName := tpl .secret.name $ }} +- name: {{ $secretName }}-mqtt-volume + mountPath: /etc/nats-certs/mqtt/{{ $secretName }} +{{- end }} +{{- with .Values.cluster.tls }} +{{- if not .custom }} +{{ $secretName := tpl .secret.name $ }} +- name: {{ $secretName }}-cluster-volume + mountPath: /etc/nats-certs/cluster/{{ $secretName }} +{{- end }} +{{- end }} +{{- with .Values.leafnodes.tls }} +{{- if not .custom }} +{{ $secretName := tpl .secret.name $ }} +- name: {{ $secretName }}-leafnodes-volume + mountPath: /etc/nats-certs/leafnodes/{{ $secretName }} +{{- end }} +{{- end }} +{{- with .Values.gateway.tls }} +{{ $secretName := tpl .secret.name $ }} +- name: {{ $secretName }}-gateways-volume + mountPath: /etc/nats-certs/gateways/{{ $secretName }} +{{- end }} +{{- with .Values.websocket.tls }} +{{ $secretName := tpl .secret.name $ }} +- name: {{ $secretName }}-ws-volume + mountPath: /etc/nats-certs/ws/{{ $secretName }} +{{- end }} +{{- end }} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "networkPolicy.apiVersion" -}} +{{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Renders a value that contains template. +Usage: +{{ include "tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define "tplvalues.render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (toYaml .value) .context }} + {{- end }} +{{- end -}} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "nats.serviceAccountName" -}} +{{- if .Values.nats.serviceAccount.create }} +{{- default (include "nats.fullname" .) .Values.nats.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.nats.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Fix image keys for chart versions <= 0.18.3 +*/}} +{{- define "nats.fixImage" -}} +{{- if kindIs "string" .image }} +{{- $_ := set . "image" (dict "repository" (split ":" .image)._0 "tag" ((split ":" .image)._1 | default "latest") "pullPolicy" "IfNotPresent") }} +{{- end }} +{{- if kindIs "string" .pullPolicy }} +{{- $_ := set .image "pullPolicy" .pullPolicy }} +{{- $_ := unset . "pullPolicy" }} +{{- end }} +{{- end }} + +{{/* +Print the image +*/}} +{{- define "nats.image" -}} +{{- $image := printf "%s:%s" .repository .tag }} +{{- if .registry }} +{{- $image = printf "%s/%s" .registry $image }} +{{- end }} +{{- $image -}} +{{- end }} diff --git a/charts/mayastor/charts/nats/templates/configmap.yaml b/charts/mayastor/charts/nats/templates/configmap.yaml new file mode 100644 index 0000000..d2f4cc3 --- /dev/null +++ b/charts/mayastor/charts/nats/templates/configmap.yaml @@ -0,0 +1,614 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "nats.fullname" . }}-config + namespace: {{ include "nats.namespace" . }} + labels: + {{- include "nats.labels" . | nindent 4 }} +data: + nats.conf: | + # NATS Clients Port + port: {{ .Values.nats.client.port }} + + # PID file shared with configuration reloader. + pid_file: "/var/run/nats/nats.pid" + + {{- if .Values.nats.config }} + ########### + # # + # Imports # + # # + ########### + {{- range .Values.nats.config }} + include ./{{ .name }}/{{ .name }}.conf + {{- end}} + {{- end }} + + ############### + # # + # Monitoring # + # # + ############### + http: 8222 + server_name: {{- if .Values.nats.serverNamePrefix }}$SERVER_NAME{{- else }}$POD_NAME{{- end }} + + {{- if .Values.nats.serverTags }} + server_tags: [ + {{- range .Values.nats.serverTags }} + "{{ . }}", + {{- end }} + ] + {{- end }} + + {{- if .Values.nats.tls }} + ##################### + # # + # TLS Configuration # + # # + ##################### + {{- with .Values.nats.tls }} + {{- $nats_tls := merge (dict) . }} + {{- $_ := set $nats_tls "secretPath" "/etc/nats-certs/clients" }} + {{- tpl (include "nats.tlsConfig" $nats_tls) $ | nindent 4}} + {{- end }} + + {{- if .Values.nats.tls.allowNonTLS }} + allow_non_tls: {{ .Values.nats.tls.allowNonTLS }} + {{- end }} + + {{- end }} + + {{- if .Values.nats.jetstream.enabled }} + ################################### + # # + # NATS JetStream # + # # + ################################### + jetstream { + {{- if .Values.nats.jetstream.encryption }} + {{- if .Values.nats.jetstream.encryption.key }} + key: {{ .Values.nats.jetstream.encryption.key | quote }} + {{- else if .Values.nats.jetstream.encryption.secret }} + key: $JS_KEY + {{- end}} + {{- if .Values.nats.jetstream.encryption.cipher }} + cipher: {{ .Values.nats.jetstream.encryption.cipher }} + {{- end}} + {{- end}} + + {{- if .Values.nats.jetstream.memStorage.enabled }} + max_mem: {{ .Values.nats.jetstream.memStorage.size }} + {{- end }} + + {{- if .Values.nats.jetstream.domain }} + domain: {{ .Values.nats.jetstream.domain }} + {{- end }} + + {{- if .Values.nats.jetstream.fileStorage.enabled }} + store_dir: {{ .Values.nats.jetstream.fileStorage.storageDirectory }} + + max_file: + {{- if .Values.nats.jetstream.fileStorage.existingClaim }} + {{- .Values.nats.jetstream.fileStorage.claimStorageSize }} + {{- else }} + {{- .Values.nats.jetstream.fileStorage.size }} + {{- end }} + {{- else }} + {{- if .Values.nats.jetstream.store_dir }} + store_dir: {{ .Values.nats.jetstream.store_dir }} + {{- end }} + {{- if .Values.nats.jetstream.max_file }} + max_file: {{ .Values.nats.jetstream.max_file }} + {{- end }} + {{- end }} + + {{- if .Values.nats.jetstream.uniqueTag }} + unique_tag: {{ .Values.nats.jetstream.uniqueTag }} + {{- end }} + + {{- if .Values.nats.jetstream.maxOutstandingCatchup }} + max_outstanding_catchup: {{ .Values.nats.jetstream.maxOutstandingCatchup }} + {{- end }} + } + {{- end }} + + {{- if .Values.nats.mappings }} + ################################### + # # + # Mappings # + # # + ################################### + mappings: {{ toRawJson .Values.nats.mappings }} + {{- end }} + + {{- if .Values.mqtt.enabled }} + ################################### + # # + # NATS MQTT # + # # + ################################### + mqtt { + port: 1883 + + {{- with .Values.mqtt.tls }} + {{- $mqtt_tls := merge (dict) . }} + {{- $_ := set $mqtt_tls "secretPath" "/etc/nats-certs/mqtt" }} + {{- tpl (include "nats.tlsConfig" $mqtt_tls) $ | nindent 6}} + {{- end }} + + {{- if .Values.mqtt.noAuthUser }} + no_auth_user: {{ .Values.mqtt.noAuthUser | quote }} + {{- end }} + + ack_wait: {{ .Values.mqtt.ackWait | quote }} + max_ack_pending: {{ .Values.mqtt.maxAckPending }} + } + {{- end }} + + {{- if .Values.cluster.enabled }} + ################################### + # # + # NATS Full Mesh Clustering Setup # + # # + ################################### + cluster { + port: 6222 + + {{- if .Values.nats.jetstream.enabled }} + {{- if .Values.cluster.name }} + name: {{ .Values.cluster.name }} + {{- else }} + name: {{ template "nats.name" . }} + {{- end }} + {{- else }} + {{- with .Values.cluster.name }} + name: {{ . }} + {{- end }} + {{- end }} + + {{- with .Values.cluster.tls }} + {{- $cluster_tls := merge (dict) . }} + {{- $_ := set $cluster_tls "secretPath" "/etc/nats-certs/cluster" }} + {{- tpl (include "nats.tlsConfig" $cluster_tls) $ | nindent 6}} + {{- end }} + + {{- if .Values.cluster.authorization }} + authorization { + {{- with .Values.cluster.authorization.user }} + user: {{ . }} + {{- end }} + {{- with .Values.cluster.authorization.password }} + password: {{ . }} + {{- end }} + {{- with .Values.cluster.authorization.timeout }} + timeout: {{ . }} + {{- end }} + } + {{- end }} + + routes = [ + {{ include "nats.clusterRoutes" . }} + {{ include "nats.extraRoutes" . }} + ] + cluster_advertise: $CLUSTER_ADVERTISE + + {{- with .Values.cluster.noAdvertise }} + no_advertise: {{ . }} + {{- end }} + + connect_retries: {{ .Values.nats.connectRetries }} + } + {{- end }} + + {{- if and .Values.nats.advertise .Values.nats.externalAccess }} + include "advertise/client_advertise.conf" + {{- end }} + + {{- if or .Values.leafnodes.enabled .Values.leafnodes.remotes }} + ################# + # # + # NATS Leafnode # + # # + ################# + leafnodes { + {{- if .Values.leafnodes.enabled }} + listen: "0.0.0.0:{{ .Values.leafnodes.port }}" + {{- end }} + + {{- if and .Values.nats.advertise .Values.nats.externalAccess }} + include "advertise/gateway_advertise.conf" + {{- end }} + + {{- with .Values.leafnodes.noAdvertise }} + no_advertise: {{ . }} + {{- end }} + + {{- with .Values.leafnodes.authorization }} + authorization: { + {{- with .user }} + user: {{ . }} + {{- end }} + {{- with .password }} + password: {{ . }} + {{- end }} + {{- with .account }} + account: {{ . | quote }} + {{- end }} + {{- with .timeout }} + timeout: {{ . }} + {{- end }} + {{- with .users }} + users: [ + {{- range . }} + {{- toRawJson . | nindent 10 }}, + {{- end }} + ] + {{- end }} + } + {{- end }} + + {{- with .Values.leafnodes.tls }} + {{- if .custom }} + tls { + {{- .custom | nindent 8 }} + } + {{- else }} + {{- $leafnode_tls := merge (dict) . }} + {{- $_ := set $leafnode_tls "secretPath" "/etc/nats-certs/leafnodes" }} + {{- tpl (include "nats.tlsConfig" $leafnode_tls) $ | nindent 6}} + {{- end }} + {{- end }} + + remotes: [ + {{- range .Values.leafnodes.remotes }} + { + {{- with .url }} + url: {{ . | quote }} + {{- end }} + + {{- with .urls }} + urls: {{ toRawJson . }} + {{- end }} + + {{- with .account }} + account: {{ . | quote }} + {{- end }} + + {{- with .credentials }} + credentials: "/etc/nats-creds/{{ .secret.name }}/{{ .secret.key }}" + {{- end }} + + {{- with .tls }} + tls: { + {{- if .custom }} + {{- .custom | nindent 10 }} + {{- else }} + {{ $secretName := tpl .secret.name $ }} + {{- with .cert }} + cert_file: /etc/nats-certs/leafnodes/{{ $secretName }}/{{ . }} + {{- end }} + + {{- with .key }} + key_file: /etc/nats-certs/leafnodes/{{ $secretName }}/{{ . }} + {{- end }} + + {{- with .ca }} + ca_file: /etc/nats-certs/leafnodes/{{ $secretName }}/{{ . }} + {{- end }} + {{- end }} + } + {{- end }} + } + {{- end }} + ] + } + {{- end }} + + {{- if .Values.gateway.enabled }} + ################# + # # + # NATS Gateways # + # # + ################# + gateway { + name: {{ .Values.gateway.name }} + port: {{ .Values.gateway.port }} + + {{- if .Values.gateway.advertise }} + advertise: {{ .Values.gateway.advertise }} + {{- end }} + + {{- if .Values.gateway.rejectUnknownCluster }} + reject_unknown_cluster: {{ .Values.gateway.rejectUnknownCluster }} + {{- end }} + + {{- if .Values.gateway.authorization }} + authorization { + {{- with .Values.gateway.authorization.user }} + user: {{ . }} + {{- end }} + {{- with .Values.gateway.authorization.password }} + password: {{ . }} + {{- end }} + {{- with .Values.gateway.authorization.timeout }} + timeout: {{ . }} + {{- end }} + } + {{- end }} + + {{- if and .Values.nats.advertise .Values.nats.externalAccess }} + include "advertise/gateway_advertise.conf" + {{- end }} + + {{- if .Values.gateway.connectRetries }} + connect_retries: {{ .Values.gateway.connectRetries }} + {{- end }} + + {{- with .Values.gateway.tls }} + {{- $gateway_tls := merge (dict) . }} + {{- $_ := set $gateway_tls "secretPath" "/etc/nats-certs/gateways" }} + {{- tpl (include "nats.tlsConfig" $gateway_tls) $ | nindent 6}} + {{- end }} + + # Gateways array here + gateways: [ + {{- range .Values.gateway.gateways }} + { + {{- with .name }} + name: {{ . }} + {{- end }} + + {{- with .url }} + url: {{ . | quote }} + {{- end }} + + {{- with .urls }} + urls: [{{ join "," . }}] + {{- end }} + }, + {{- end }} + ] + } + {{- end }} + + {{- with .Values.nats.logging.debug }} + debug: {{ . }} + {{- end }} + + {{- with .Values.nats.logging.trace }} + trace: {{ . }} + {{- end }} + + {{- with .Values.nats.logging.logtime }} + logtime: {{ . }} + {{- end }} + + {{- with .Values.nats.logging.connectErrorReports }} + connect_error_reports: {{ . }} + {{- end }} + + {{- with .Values.nats.logging.reconnectErrorReports }} + reconnect_error_reports: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.maxConnections }} + max_connections: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.maxSubscriptions }} + max_subscriptions: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.maxPending }} + max_pending: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.maxControlLine }} + max_control_line: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.maxPayload }} + max_payload: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.pingInterval }} + ping_interval: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.maxPings }} + ping_max: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.writeDeadline }} + write_deadline: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.lameDuckGracePeriod }} + lame_duck_grace_period: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.lameDuckDuration }} + lame_duck_duration: {{ . }} + {{- end }} + + {{- if .Values.websocket.enabled }} + ################## + # # + # Websocket # + # # + ################## + websocket { + port: {{ .Values.websocket.port }} + {{- with .Values.websocket.tls }} + {{ $secretName := tpl .secret.name $ }} + tls { + {{- with .cert }} + cert_file: /etc/nats-certs/ws/{{ $secretName }}/{{ . }} + {{- end }} + + {{- with .key }} + key_file: /etc/nats-certs/ws/{{ $secretName }}/{{ . }} + {{- end }} + + {{- with .ca }} + ca_file: /etc/nats-certs/ws/{{ $secretName }}/{{ . }} + {{- end }} + } + {{- else }} + no_tls: {{ .Values.websocket.noTLS }} + {{- end }} + same_origin: {{ .Values.websocket.sameOrigin }} + {{- with .Values.websocket.allowedOrigins }} + allowed_origins: {{ toRawJson . }} + {{- end }} + {{- with .Values.websocket.advertise }} + advertise: {{ . }} + {{- end }} + {{- with .Values.websocket.handshakeTimeout }} + handshake_timeout: {{ . | quote }} + {{- end }} + } + {{- end }} + + {{- if .Values.auth.enabled }} + ################## + # # + # Authorization # + # # + ################## + {{- if .Values.auth.resolver }} + {{- if eq .Values.auth.resolver.type "memory" }} + resolver: MEMORY + include "accounts/{{ .Values.auth.resolver.configMap.key }}" + {{- end }} + + {{- if eq .Values.auth.resolver.type "full" }} + {{- if .Values.auth.resolver.configMap }} + include "accounts/{{ .Values.auth.resolver.configMap.key }}" + {{- else }} + {{- with .Values.auth.resolver }} + {{- if $.Values.auth.timeout }} + authorization { + timeout: {{ $.Values.auth.timeout }} + } + {{- end }} + + {{- if .operator }} + operator: {{ .operator }} + {{- end }} + + {{- if .systemAccount }} + system_account: {{ .systemAccount | quote }} + {{- end }} + {{- end }} + + resolver: { + type: full + {{- with .Values.auth.resolver }} + dir: {{ .store.dir | quote }} + + allow_delete: {{ .allowDelete }} + + interval: {{ .interval | quote }} + {{- end }} + } + {{- end }} + {{- end }} + + {{- if .Values.auth.resolver.resolverPreload }} + resolver_preload: {{ toRawJson .Values.auth.resolver.resolverPreload }} + {{- end }} + + {{- if eq .Values.auth.resolver.type "URL" }} + {{- with .Values.auth.resolver.url }} + resolver: URL({{ . }}) + {{- end }} + operator: /etc/nats-config/operator/{{ .Values.auth.operatorjwt.configMap.key }} + {{- end }} + {{- end }} + + {{- with .Values.auth.systemAccount }} + system_account: {{ . | quote }} + {{- end }} + + {{- with .Values.auth.token }} + authorization { + token: "{{ . }}" + + + {{- if $.Values.auth.timeout }} + timeout: {{ $.Values.auth.timeout }} + {{- end }} + } + {{- end }} + + {{- with .Values.auth.nkeys }} + {{- with .users }} + authorization { + {{- if $.Values.auth.timeout }} + timeout: {{ $.Values.auth.timeout }} + {{- end }} + + users: [ + {{- range . }} + {{- toRawJson . | nindent 8 }}, + {{- end }} + ] + } + {{- end }} + {{- end }} + + {{- with .Values.auth.basic }} + + {{- with .noAuthUser }} + no_auth_user: {{ . }} + {{- end }} + + {{- if or .users (or .timeout .defaultPermissions) }} + authorization { + {{- if $.Values.auth.timeout }} + timeout: {{ $.Values.auth.timeout }} + {{- end }} + + {{- with .users }} + users: [ + {{- range . }} + {{- toRawJson . | nindent 8 }}, + {{- end }} + ] + {{- end }} + + {{- with $.Values.auth.basic.defaultPermissions }} + default_permissions: { + {{- if .publish }} + publish: [ + {{- range .publish }} + {{- toRawJson . | nindent 10 }}, + {{- end }} + ], + {{- end }} + {{- if .subscribe }} + subscribe: [ + {{- range .subscribe }} + {{- toRawJson . | nindent 10 }}, + {{- end }} + ], + {{- end }} + } + {{- end }} + } + {{- end }} + + {{- with .accounts }} + authorization { + {{- if $.Values.auth.timeout }} + timeout: {{ $.Values.auth.timeout }} + {{- end }} + } + accounts: {{- toRawJson . }} + {{- end }} + + {{- end }} + + {{- end }} diff --git a/charts/mayastor/charts/nats/templates/nats-box.yaml b/charts/mayastor/charts/nats/templates/nats-box.yaml new file mode 100644 index 0000000..e94362f --- /dev/null +++ b/charts/mayastor/charts/nats/templates/nats-box.yaml @@ -0,0 +1,121 @@ +{{- if .Values.natsbox.enabled }} +{{- include "nats.fixImage" .Values.natsbox -}} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "nats.fullname" . }}-box + namespace: {{ include "nats.namespace" . }} + labels: + app: {{ include "nats.fullname" . }}-box + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + {{- if .Values.natsbox.additionalLabels }} + {{- tpl (toYaml .Values.natsbox.additionalLabels) $ | nindent 4 }} + {{- end }} + {{- if .Values.natsbox.annotations }} + annotations: + {{- toYaml .Values.natsbox.annotations | nindent 4 }} + {{- end }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ include "nats.fullname" . }}-box + template: + metadata: + labels: + app: {{ include "nats.fullname" . }}-box + {{- if .Values.natsbox.podLabels }} + {{- tpl (toYaml .Values.natsbox.podLabels) $ | nindent 8 }} + {{- end }} + {{- if .Values.natsbox.podAnnotations }} + annotations: + {{- toYaml .Values.natsbox.podAnnotations | nindent 8 }} + {{- end }} + spec: + {{- with .Values.natsbox.affinity }} + affinity: + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.natsbox.nodeSelector }} + nodeSelector: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.natsbox.tolerations }} + tolerations: {{ toYaml . | nindent 8 }} + {{- end }} + volumes: + {{- if .Values.natsbox.credentials }} + - name: nats-sys-creds + secret: + secretName: {{ .Values.natsbox.credentials.secret.name }} + {{- end }} + {{- if .Values.natsbox.extraVolumes }} + {{- toYaml .Values.natsbox.extraVolumes | nindent 6}} + {{- end }} + {{- with .Values.nats.tls }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-clients-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if hasKey .Values.natsbox "automountServiceAccountToken" }} + automountServiceAccountToken: {{ .Values.natsbox.automountServiceAccountToken }} + {{- end }} + containers: + - name: nats-box + image: {{ include "nats.image" .Values.natsbox.image }} + imagePullPolicy: {{ .Values.natsbox.image.pullPolicy }} + {{- if .Values.natsbox.securityContext }} + securityContext: + {{- toYaml .Values.natsbox.securityContext | nindent 10 }} + {{- end }} + resources: + {{- toYaml .Values.natsbox.resources | nindent 10 }} + env: + - name: NATS_URL + value: {{ template "nats.fullname" . }} + {{- if .Values.natsbox.credentials }} + - name: NATS_CREDS + value: /etc/nats-config/creds/{{ .Values.natsbox.credentials.secret.key }} + {{- end }} + {{- with .Values.nats.tls }} + {{ $secretName := tpl .secret.name $ }} + lifecycle: + postStart: + exec: + command: + - /bin/sh + - -c + - cp /etc/nats-certs/clients/{{ $secretName }}/* /usr/local/share/ca-certificates && update-ca-certificates + {{- end }} + command: + - "tail" + - "-f" + - "/dev/null" + volumeMounts: + {{- if .Values.natsbox.credentials }} + - name: nats-sys-creds + mountPath: /etc/nats-config/creds + {{- end }} + {{- if .Values.natsbox.extraVolumeMounts }} + {{- toYaml .Values.natsbox.extraVolumeMounts | nindent 8 }} + {{- end }} + {{- with .Values.nats.tls }} + ####################### + # # + # TLS Volumes Mounts # + # # + ####################### + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-clients-volume + mountPath: /etc/nats-certs/clients/{{ $secretName }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/nats/templates/networkpolicy.yaml b/charts/mayastor/charts/nats/templates/networkpolicy.yaml new file mode 100644 index 0000000..9951441 --- /dev/null +++ b/charts/mayastor/charts/nats/templates/networkpolicy.yaml @@ -0,0 +1,79 @@ +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ template "networkPolicy.apiVersion" . }} +metadata: + name: {{ include "nats.fullname" . }} + namespace: {{ include "nats.namespace" . }} + labels: + {{- include "nats.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "nats.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + - Egress + egress: + # Allow dns resolution + - ports: + - port: 53 + protocol: UDP + # Allow outbound connections to other cluster pods + - ports: + - port: {{ .Values.nats.client.port }} + protocol: TCP + - port: 6222 + protocol: TCP + - port: 8222 + protocol: TCP + - port: 7777 + protocol: TCP + - port: {{ .Values.leafnodes.port }} + protocol: TCP + - port: {{ .Values.gateway.port }} + protocol: TCP + to: + - podSelector: + matchLabels: + {{- include "nats.selectorLabels" . | nindent 10 }} + {{- if .Values.networkPolicy.extraEgress }} + {{- include "tplvalues.render" ( dict "value" .Values.networkPolicy.extraEgress "context" $ ) | nindent 2 }} + {{- end }} + ingress: + # Allow inbound connections + - ports: + - port: {{ .Values.nats.client.port }} + protocol: TCP + - port: 6222 + protocol: TCP + - port: 8222 + protocol: TCP + - port: 7777 + protocol: TCP + - port: {{ .Values.leafnodes.port }} + protocol: TCP + - port: {{ .Values.gateway.port }} + protocol: TCP + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ include "nats.fullname" . }}-client: "true" + - podSelector: + matchLabels: + {{- include "nats.selectorLabels" . | nindent 10 }} + {{- if .Values.networkPolicy.ingressNSMatchLabels }} + - namespaceSelector: + matchLabels: + {{- toYaml .Values.networkPolicy.ingressNSMatchLabels | nindent 10 }} + {{- if .Values.networkPolicy.ingressNSPodMatchLabels }} + podSelector: + matchLabels: + {{- toYaml .Values.networkPolicy.ingressNSPodMatchLabels | nindent 10 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.networkPolicy.extraIngress }} + {{- include "tplvalues.render" ( dict "value" .Values.networkPolicy.extraIngress "context" $ ) | nindent 2 }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/charts/nats/templates/pdb.yaml b/charts/mayastor/charts/nats/templates/pdb.yaml new file mode 100644 index 0000000..5a7cb43 --- /dev/null +++ b/charts/mayastor/charts/nats/templates/pdb.yaml @@ -0,0 +1,20 @@ +{{- if .Values.podDisruptionBudget.enabled }} +--- +apiVersion: {{ .Capabilities.APIVersions.Has "policy/v1" | ternary "policy/v1" "policy/v1beta1" }} +kind: PodDisruptionBudget +metadata: + name: {{ include "nats.fullname" . }} + namespace: {{ include "nats.namespace" . }} + labels: + {{- include "nats.labels" . | nindent 4 }} +spec: + {{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "nats.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/mayastor/charts/nats/templates/rbac.yaml b/charts/mayastor/charts/nats/templates/rbac.yaml new file mode 100644 index 0000000..7b55aeb --- /dev/null +++ b/charts/mayastor/charts/nats/templates/rbac.yaml @@ -0,0 +1,39 @@ +{{- if or (.Values.nats.serviceAccount.create) (and .Values.nats.externalAccess .Values.nats.advertise) }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "nats.serviceAccountName" . }} + namespace: {{ include "nats.namespace" . }} + labels: + {{- include "nats.labels" . | nindent 4 }} + {{- with .Values.nats.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- if and .Values.nats.externalAccess .Values.nats.advertise }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "nats.serviceAccountName" . }} +rules: +- apiGroups: [""] + resources: + - nodes + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "nats.serviceAccountName" . }}-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "nats.serviceAccountName" . }} +subjects: +- kind: ServiceAccount + name: {{ include "nats.serviceAccountName" . }} + namespace: {{ include "nats.namespace" . }} +{{- end }} diff --git a/charts/mayastor/charts/nats/templates/service.yaml b/charts/mayastor/charts/nats/templates/service.yaml new file mode 100644 index 0000000..361e725 --- /dev/null +++ b/charts/mayastor/charts/nats/templates/service.yaml @@ -0,0 +1,74 @@ +{{- $appProtocol := semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "nats.fullname" . }} + namespace: {{ include "nats.namespace" . }} + labels: + {{- include "nats.labels" . | nindent 4 }} + {{- if .Values.serviceAnnotations}} + annotations: + {{- toYaml .Values.serviceAnnotations | nindent 4 }} + {{- end }} +spec: + selector: + {{- include "nats.selectorLabels" . | nindent 4 }} + clusterIP: None + publishNotReadyAddresses: true + {{- if .Values.topologyKeys }} + topologyKeys: + {{- toYaml .Values.topologyKeys | nindent 4 }} + {{- end }} + ports: + {{- if .Values.websocket.enabled }} + - name: websocket + port: {{ .Values.websocket.port }} + {{- if $appProtocol }} + appProtocol: tcp + {{- end }} + {{- end }} + {{- if .Values.nats.profiling.enabled }} + - name: profiling + port: {{ .Values.nats.profiling.port }} + {{- if $appProtocol }} + appProtocol: http + {{- end }} + {{- end }} + - name: {{ .Values.nats.client.portName }} + port: {{ .Values.nats.client.port }} + {{- if $appProtocol }} + appProtocol: tcp + {{- end }} + - name: cluster + port: 6222 + {{- if $appProtocol }} + appProtocol: tcp + {{- end }} + - name: monitor + port: 8222 + {{- if $appProtocol }} + appProtocol: http + {{- end }} + - name: {{ .Values.exporter.portName }} + port: 7777 + {{- if $appProtocol }} + appProtocol: http + {{- end }} + - name: leafnodes + port: {{ .Values.leafnodes.port }} + {{- if $appProtocol }} + appProtocol: tcp + {{- end }} + - name: gateways + port: {{ .Values.gateway.port }} + {{- if $appProtocol }} + appProtocol: tcp + {{- end }} + {{- if .Values.mqtt.enabled }} + - name: mqtt + port: 1883 + {{- if $appProtocol }} + appProtocol: tcp + {{- end }} + {{- end }} diff --git a/charts/mayastor/charts/nats/templates/serviceMonitor.yaml b/charts/mayastor/charts/nats/templates/serviceMonitor.yaml new file mode 100644 index 0000000..282f50f --- /dev/null +++ b/charts/mayastor/charts/nats/templates/serviceMonitor.yaml @@ -0,0 +1,36 @@ +{{ if and .Values.exporter.enabled .Values.exporter.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "nats.fullname" . }} + {{- if .Values.exporter.serviceMonitor.namespace }} + namespace: {{ .Values.exporter.serviceMonitor.namespace }} + {{- else }} + namespace: {{ include "nats.namespace" . }} + {{- end }} + {{- if .Values.exporter.serviceMonitor.labels }} + labels: + {{- toYaml .Values.exporter.serviceMonitor.labels | nindent 4 }} + {{- end }} + {{- if .Values.exporter.serviceMonitor.annotations }} + annotations: + {{- toYaml .Values.exporter.serviceMonitor.annotations | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.exporter.portName }} + {{- if .Values.exporter.serviceMonitor.path }} + path: {{ .Values.exporter.serviceMonitor.path }} + {{- end }} + {{- if .Values.exporter.serviceMonitor.interval }} + interval: {{ .Values.exporter.serviceMonitor.interval }} + {{- end }} + {{- if .Values.exporter.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.exporter.serviceMonitor.scrapeTimeout }} + {{- end }} + namespaceSelector: + any: true + selector: + matchLabels: + {{- include "nats.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/mayastor/charts/nats/templates/statefulset.yaml b/charts/mayastor/charts/nats/templates/statefulset.yaml new file mode 100644 index 0000000..1ea285f --- /dev/null +++ b/charts/mayastor/charts/nats/templates/statefulset.yaml @@ -0,0 +1,650 @@ +{{- include "nats.fixImage" .Values.nats -}} +{{- include "nats.fixImage" .Values.bootconfig -}} +{{- include "nats.fixImage" .Values.reloader -}} +{{- include "nats.fixImage" .Values.exporter -}} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "nats.fullname" . }} + namespace: {{ include "nats.namespace" . }} + labels: + {{- include "nats.labels" . | nindent 4 }} + {{- if .Values.statefulSetAnnotations }} + annotations: + {{- toYaml .Values.statefulSetAnnotations | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "nats.selectorLabels" . | nindent 6 }} + {{- if .Values.cluster.enabled }} + replicas: {{ .Values.cluster.replicas }} + {{- else }} + replicas: 1 + {{- end }} + serviceName: {{ include "nats.fullname" . }} + + podManagementPolicy: {{ .Values.podManagementPolicy }} + + template: + metadata: + {{- if or .Values.exporter.enabled .Values.nats.configChecksumAnnotation .Values.podAnnotations }} + annotations: + {{- if .Values.exporter.enabled }} + prometheus.io/path: /metrics + prometheus.io/port: "7777" + prometheus.io/scrape: "true" + {{- end }} + {{- if .Values.nats.configChecksumAnnotation }} + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.podAnnotations }} + {{- toYaml .Values.podAnnotations | nindent 8 }} + {{- end }} + {{- end }} + labels: + {{- include "nats.selectorLabels" . | nindent 8 }} + {{- if .Values.statefulSetPodLabels }} + {{- tpl (toYaml .Values.statefulSetPodLabels) . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: {{ toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- range .Values.topologySpreadConstraints }} + {{- if and .maxSkew .topologyKey }} + - maxSkew: {{ .maxSkew }} + topologyKey: {{ .topologyKey }} + {{- if .whenUnsatisfiable }} + whenUnsatisfiable: {{ .whenUnsatisfiable }} + {{- end }} + labelSelector: + matchLabels: + {{- include "nats.selectorLabels" $ | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + {{- with .Values.nats.dnsPolicy }} + dnsPolicy: {{ . }} + {{- end }} + {{- with .Values.nats.hostNetwork }} + hostNetwork: {{ . }} + {{- end }} + # Common volumes for the containers. + volumes: + - name: config-volume + {{- if .Values.nats.customConfigSecret }} + secret: + secretName: {{ .Values.nats.customConfigSecret.name }} + {{- else }} + configMap: + name: {{ include "nats.fullname" . }}-config + {{- end }} + + {{- /* User extended config volumes*/}} + {{- if .Values.nats.config }} + # User extended config volumes + {{- with .Values.nats.config }} + {{- toYaml . | nindent 6 }} + {{- end }} + {{- end }} + + # Local volume shared with the reloader. + - name: pid + {{- toYaml .Values.pidVolume | nindent 8 }} + + {{- if and .Values.auth.enabled .Values.auth.resolver }} + {{- if .Values.auth.resolver.configMap }} + - name: resolver-volume + configMap: + name: {{ .Values.auth.resolver.configMap.name }} + {{- end }} + + {{- if eq .Values.auth.resolver.type "URL" }} + - name: operator-jwt-volume + configMap: + name: {{ .Values.auth.operatorjwt.configMap.name }} + {{- end }} + {{- end }} + + {{- if and .Values.nats.externalAccess .Values.nats.advertise }} + # Local volume shared with the advertise config initializer. + - name: advertiseconfig + {{- toYaml .Values.advertiseconfigVolume | nindent 8 }} + {{- end }} + + {{- if and .Values.nats.jetstream.enabled .Values.nats.jetstream.fileStorage.enabled .Values.nats.jetstream.fileStorage.existingClaim }} + # Persistent volume for jetstream running with file storage option + - name: {{ include "nats.fullname" . }}-js-pvc + persistentVolumeClaim: + claimName: {{ .Values.nats.jetstream.fileStorage.existingClaim | quote }} + {{- end }} + + ################# + # # + # TLS Volumes # + # # + ################# + {{- with .Values.nats.tls }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-clients-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- with .Values.mqtt.tls }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-mqtt-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- with .Values.cluster.tls }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-cluster-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- with .Values.leafnodes.tls }} + {{- if not .custom }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-leafnodes-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- end }} + {{- with .Values.gateway.tls }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-gateways-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- with .Values.websocket.tls }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-ws-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- if .Values.leafnodes.enabled }} + # + # Leafnode credential volumes + # + {{- range .Values.leafnodes.remotes }} + {{- with .credentials }} + - name: {{ .secret.name }}-volume + secret: + secretName: {{ .secret.name }} + {{- end }} + {{- with .tls }} + - name: {{ .secret.name }}-volume + secret: + secretName: {{ .secret.name }} + {{- end }} + {{- end }} + {{- end }} + + {{- if .Values.additionalVolumes }} + {{- toYaml .Values.additionalVolumes | nindent 6 }} + {{- end }} + + serviceAccountName: {{ include "nats.serviceAccountName" . }} + {{- if hasKey .Values.nats "automountServiceAccountToken" }} + automountServiceAccountToken: {{ .Values.nats.automountServiceAccountToken }} + {{- end }} + + # Required to be able to HUP signal and apply config + # reload to the server without restarting the pod. + shareProcessNamespace: true + + {{- if and .Values.nats.externalAccess .Values.nats.advertise }} + # Initializer container required to be able to lookup + # the external ip on which this node is running. + initContainers: + - name: bootconfig + command: + - nats-pod-bootconfig + - -f + - /etc/nats-config/advertise/client_advertise.conf + - -gf + - /etc/nats-config/advertise/gateway_advertise.conf + env: + - name: KUBERNETES_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + image: {{ include "nats.image" .Values.bootconfig.image }} + imagePullPolicy: {{ .Values.bootconfig.image.pullPolicy }} + {{- if .Values.bootconfig.securityContext }} + securityContext: + {{- toYaml .Values.bootconfig.securityContext | nindent 10 }} + {{- end }} + resources: + {{- toYaml .Values.bootconfig.resources | nindent 10 }} + volumeMounts: + - mountPath: /etc/nats-config/advertise + name: advertiseconfig + subPath: advertise + {{- end }} + + ################# + # # + # NATS Server # + # # + ################# + terminationGracePeriodSeconds: {{ .Values.nats.terminationGracePeriodSeconds }} + containers: + - name: nats + image: {{ include "nats.image" .Values.nats.image }} + imagePullPolicy: {{ .Values.nats.image.pullPolicy }} + {{- if .Values.nats.securityContext }} + securityContext: + {{- toYaml .Values.nats.securityContext | nindent 10 }} + {{- end }} + resources: + {{- toYaml .Values.nats.resources | nindent 10 }} + ports: + - containerPort: {{ .Values.nats.client.port }} + name: {{ .Values.nats.client.portName }} + {{- if .Values.nats.externalAccess }} + hostPort: {{ .Values.nats.client.port }} + {{- end }} + {{- if .Values.leafnodes.enabled }} + - containerPort: {{ .Values.leafnodes.port }} + name: leafnodes + {{- if .Values.nats.externalAccess }} + hostPort: {{ .Values.leafnodes.port }} + {{- end }} + {{- end }} + {{- if .Values.gateway.enabled }} + - containerPort: {{ .Values.gateway.port }} + name: gateways + {{- if .Values.nats.externalAccess }} + hostPort: {{ .Values.gateway.port }} + {{- end }} + {{- end }} + - containerPort: 6222 + name: cluster + - containerPort: 8222 + name: monitor + {{- if .Values.mqtt.enabled }} + - containerPort: 1883 + name: mqtt + {{- if .Values.nats.externalAccess }} + hostPort: 1883 + {{- end }} + {{- end }} + {{- if .Values.websocket.enabled }} + - containerPort: {{ .Values.websocket.port }} + name: websocket + {{- if .Values.nats.externalAccess }} + hostPort: {{ .Values.websocket.port }} + {{- end }} + {{- end }} + {{- if .Values.nats.profiling.enabled }} + - containerPort: {{ .Values.nats.profiling.port }} + name: profiling + {{- end }} + + command: + - "nats-server" + - "--config" + - "/etc/nats-config/nats.conf" + {{- if .Values.nats.profiling.enabled }} + - "--profile={{ .Values.nats.profiling.port }}" + {{- end }} + + # Required to be able to define an environment variable + # that refers to other environment variables. This env var + # is later used as part of the configuration file. + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: SERVER_NAME + value: {{ .Values.nats.serverNamePrefix }}$(POD_NAME) + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: CLUSTER_ADVERTISE + value: {{ include "nats.clusterAdvertise" . }} + {{- if .Values.nats.gomemlimit }} + - name: GOMEMLIMIT + value: {{ .Values.nats.gomemlimit | quote }} + {{- end }} + {{- if .Values.nats.extraEnv }} + {{- toYaml .Values.nats.extraEnv | nindent 8 }} + {{- end }} + + {{- if .Values.nats.jetstream.enabled }} + {{- with .Values.nats.jetstream.encryption }} + {{- with .secret }} + - name: JS_KEY + valueFrom: + secretKeyRef: + name: {{ .name }} + key: {{ .key }} + {{- end }} + {{- end }} + {{- end }} + volumeMounts: + - name: config-volume + mountPath: /etc/nats-config + - name: pid + mountPath: /var/run/nats + {{- if and .Values.nats.externalAccess .Values.nats.advertise }} + - mountPath: /etc/nats-config/advertise + name: advertiseconfig + subPath: advertise + {{- end }} + + {{- /* User extended config volumes*/}} + {{- range .Values.nats.config }} + # User extended config volumes + - name: {{ .name }} + mountPath: /etc/nats-config/{{ .name }} + {{- end }} + + + {{- if and .Values.auth.enabled .Values.auth.resolver }} + {{- if eq .Values.auth.resolver.type "memory" }} + - name: resolver-volume + mountPath: /etc/nats-config/accounts + {{- end }} + + {{- if eq .Values.auth.resolver.type "full" }} + {{- if .Values.auth.resolver.configMap }} + - name: resolver-volume + mountPath: /etc/nats-config/accounts + {{- end }} + {{- if and .Values.auth.resolver .Values.auth.resolver.store }} + - name: nats-jwt-pvc + mountPath: {{ .Values.auth.resolver.store.dir }} + {{- end }} + {{- end }} + + {{- if eq .Values.auth.resolver.type "URL" }} + - name: operator-jwt-volume + mountPath: /etc/nats-config/operator + {{- end }} + {{- end }} + + {{- if and .Values.nats.jetstream.enabled .Values.nats.jetstream.fileStorage.enabled }} + - name: {{ include "nats.fullname" . }}-js-pvc + mountPath: {{ .Values.nats.jetstream.fileStorage.storageDirectory }} + {{- end }} + + {{- include "nats.tlsVolumeMounts" . | nindent 8 }} + + {{- if .Values.leafnodes.enabled }} + # + # Leafnode credential volumes + # + {{- range .Values.leafnodes.remotes }} + {{- with .credentials }} + - name: {{ .secret.name }}-volume + mountPath: /etc/nats-creds/{{ .secret.name }} + {{- end }} + {{- with .tls }} + - name: {{ .secret.name }}-volume + mountPath: /etc/nats-certs/leafnodes/{{ .secret.name }} + {{- end }} + {{- end }} + {{- end }} + + {{- if .Values.additionalVolumeMounts }} + {{- toYaml .Values.additionalVolumeMounts | nindent 8 }} + {{- end }} + + ####################### + # # + # Healthcheck Probes # + # # + ####################### + {{- if .Values.nats.healthcheck }} + {{- $serverVersion := .Values.nats.image.tag | regexFind "\\d+(\\.\\d+)?(\\.\\d+)?" | default "2.9.0" }} + {{- $enableHealthzStartup := and .Values.nats.healthcheck.enableHealthz (or (not .Values.nats.healthcheck.detectHealthz) (semverCompare ">=2.7.1" $serverVersion)) }} + {{- $enableHealthzLivenessReadiness := and .Values.nats.healthcheck.enableHealthzLivenessReadiness (or (not .Values.nats.healthcheck.detectHealthz) (semverCompare ">=2.9.0" $serverVersion)) }} + {{- $healthzStartupEndpoint := "/healthz" }} + {{- $healthzLivenessEndpoint := "/healthz?js-enabled-only=true" }} + {{- $healthzReadinessEndpoint := "/healthz?js-server-only=true" }} + + {{- /* healthz options behaved differently in 2.9.0 - 2.9.9 https://github.com/nats-io/nats-server/pull/3704 */}} + {{- if (semverCompare "<=2.9.9" $serverVersion) }} + {{- $healthzLivenessEndpoint = "/healthz?js-server-only=true" }} + {{- $healthzReadinessEndpoint = "/healthz?js-server-only=true" }} + {{- if .Values.nats.jetstream.enabled }} + {{- $healthzLivenessEndpoint = print $healthzLivenessEndpoint "&js-enabled=true" }} + {{- $healthzReadinessEndpoint = print $healthzReadinessEndpoint "&js-enabled=true" }} + {{- end }} + {{- end }} + + {{- with .Values.nats.healthcheck.liveness }} + {{- if .enabled }} + livenessProbe: + {{- $probe := merge (dict) . }} + {{- $_ := unset $probe "enabled" }} + {{- $probeDefault := dict "httpGet" (dict "path" "/" "port" 8222) }} + {{- if $enableHealthzLivenessReadiness }} + # for NATS server versions >=2.9.0, {{ $healthzLivenessEndpoint }} will be enabled + # liveness probe checks that the JS server is enabled + {{- $_ := set $probeDefault.httpGet "path" $healthzLivenessEndpoint }} + {{- end }} + {{- $probe := merge $probe $probeDefault }} + {{- toYaml $probe | nindent 10}} + {{- end }} + {{- end }} + + {{- with .Values.nats.healthcheck.readiness }} + {{- if .enabled }} + readinessProbe: + {{- $probe := merge (dict) . }} + {{- $_ := unset $probe "enabled" }} + {{- $probeDefault := dict "httpGet" (dict "path" "/" "port" 8222) }} + {{- if $enableHealthzLivenessReadiness }} + # for NATS server versions >=2.9.0, {{ $healthzReadinessEndpoint }} will be enabled + # readiness probe checks that the JS server is enabled, and is current with the meta leader + {{- $_ := set $probeDefault.httpGet "path" $healthzReadinessEndpoint }} + {{- end }} + {{- $probe := merge $probe $probeDefault }} + {{- toYaml $probe | nindent 10}} + {{- end }} + {{- end }} + + {{- with .Values.nats.healthcheck.startup }} + {{- if .enabled }} + startupProbe: + {{- $probe := merge (dict) . }} + {{- $_ := unset $probe "enabled" }} + {{- $probeDefault := dict "httpGet" (dict "path" "/" "port" 8222) }} + {{- if $enableHealthzStartup }} + # for NATS server versions >=2.7.1, {{ $healthzStartupEndpoint}} will be enabled + # startup probe checks that the JS server is enabled, is current with the meta leader, + # and that all streams and consumers assigned to this JS server are current + {{- $_ := set $probeDefault.httpGet "path" $healthzStartupEndpoint }} + {{- end }} + {{- $probe := merge $probe $probeDefault }} + {{- toYaml $probe | nindent 10}} + {{- end }} + {{- end }} + + {{- end }} + + # Gracefully stop NATS Server on pod deletion or image upgrade. + # + lifecycle: + preStop: + exec: + # send the lame duck shutdown signal to trigger a graceful shutdown + # nats-server will ignore the TERM signal it receives after this + # + command: + - "nats-server" + - "-sl=ldm=/var/run/nats/nats.pid" + + ################################# + # # + # NATS Configuration Reloader # + # # + ################################# + {{- if .Values.reloader.enabled }} + - name: reloader + image: {{ include "nats.image" .Values.reloader.image }} + imagePullPolicy: {{ .Values.reloader.image.pullPolicy }} + {{- if .Values.reloader.securityContext }} + securityContext: + {{- toYaml .Values.reloader.securityContext | nindent 10 }} + {{- end }} + resources: + {{- toYaml .Values.reloader.resources | nindent 10 }} + command: + - "nats-server-config-reloader" + - "-pid" + - "/var/run/nats/nats.pid" + - "-config" + - "/etc/nats-config/nats.conf" + {{- with .Values.nats.tls }} + {{- $nats_tls := merge (dict) . }} + {{- $_ := set $nats_tls "secretPath" "/etc/nats-certs/clients" }} + {{- tpl (include "nats.tlsReloaderArgs" $nats_tls) $ | nindent 8}} + {{- end }} + {{- with .Values.cluster.tls }} + {{- $nats_tls := merge (dict) . }} + {{- $_ := set $nats_tls "secretPath" "/etc/nats-certs/cluster" }} + {{- tpl (include "nats.tlsReloaderArgs" $nats_tls) $ | nindent 8}} + {{- end }} + {{- range .Values.reloader.extraConfigs }} + - "-config" + - {{ . | quote }} + {{- end }} + {{- range .Values.nats.config }} + - "-config" + - "/etc/nats-config/{{ .name }}/{{ .name }}.conf" + {{- end}} + volumeMounts: + - name: config-volume + mountPath: /etc/nats-config + - name: pid + mountPath: /var/run/nats + {{- include "nats.tlsVolumeMounts" . | nindent 8 }} + {{- if .Values.additionalVolumeMounts }} + {{- toYaml .Values.additionalVolumeMounts | nindent 8 }} + {{- end }} + {{- /* User extended config volumes*/}} + {{- range .Values.nats.config }} + # User extended config volumes + - name: {{ .name }} + mountPath: /etc/nats-config/{{ .name }} + {{- end }} + {{- end }} + + ############################## + # # + # NATS Prometheus Exporter # + # # + ############################## + {{- if .Values.exporter.enabled }} + - name: metrics + image: {{ include "nats.image" .Values.exporter.image }} + imagePullPolicy: {{ .Values.exporter.image.pullPolicy }} + {{- if .Values.exporter.securityContext }} + securityContext: + {{- toYaml .Values.exporter.securityContext | nindent 10 }} + {{- end }} + resources: + {{- toYaml .Values.exporter.resources | nindent 10 }} + args: + {{- if .Values.exporter.args }} + {{- toYaml .Values.exporter.args | nindent 8 }} + {{- else }} + - -connz + - -routez + - -subz + - -varz + - -prefix=nats + - -use_internal_server_id + {{- if .Values.nats.jetstream.enabled }} + - -jsz=all + {{- end }} + {{- if .Values.leafnodes.enabled }} + - -leafz + {{- end }} + {{- if .Values.gateway.enabled }} + - -gatewayz + {{- end }} + - http://localhost:8222/ + {{- end }} + ports: + - containerPort: 7777 + name: {{ .Values.exporter.portName }} + {{- end }} + + {{- if .Values.additionalContainers }} + {{- toYaml .Values.additionalContainers | nindent 6 }} + {{- end }} + + volumeClaimTemplates: + {{- if eq .Values.auth.resolver.type "full" }} + {{- if and .Values.auth.resolver .Values.auth.resolver.store }} + ##################################### + # # + # Account Server Embedded JWT # + # # + ##################################### + - metadata: + name: nats-jwt-pvc + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.auth.resolver.store.size }} + {{- if .Values.auth.resolver.store.storageClassName }} + storageClassName: {{ .Values.auth.resolver.store.storageClassName | quote }} + {{- end }} + {{- end }} + {{- end }} + + {{- if and .Values.nats.jetstream.enabled .Values.nats.jetstream.fileStorage.enabled (not .Values.nats.jetstream.fileStorage.existingClaim) }} + ##################################### + # # + # Jetstream New Persistent Volume # + # # + ##################################### + - metadata: + name: {{ include "nats.fullname" . }}-js-pvc + {{- if .Values.nats.jetstream.fileStorage.annotations }} + annotations: + {{- toYaml .Values.nats.jetstream.fileStorage.annotations | nindent 10 }} + {{- end }} + spec: + accessModes: + {{- toYaml .Values.nats.jetstream.fileStorage.accessModes | nindent 10 }} + resources: + requests: + storage: {{ .Values.nats.jetstream.fileStorage.size }} + {{- if .Values.nats.jetstream.fileStorage.storageClassName }} + storageClassName: {{ .Values.nats.jetstream.fileStorage.storageClassName | quote }} + {{- end }} + {{- end }} diff --git a/charts/mayastor/charts/nats/templates/tests/test-request-reply.yaml b/charts/mayastor/charts/nats/templates/tests/test-request-reply.yaml new file mode 100644 index 0000000..829aca2 --- /dev/null +++ b/charts/mayastor/charts/nats/templates/tests/test-request-reply.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "nats.fullname" . }}-test-request-reply" + labels: + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app: {{ include "nats.fullname" . }}-test-request-reply + annotations: + "helm.sh/hook": test +spec: + containers: + - name: nats-box + image: {{ include "nats.image" .Values.natsbox.image }} + env: + - name: NATS_HOST + value: {{ template "nats.fullname" . }} + command: + - /bin/sh + - -ec + - | + nats reply -s nats://$NATS_HOST:{{ .Values.nats.client.port }} 'name.>' --command "echo {{1}}" & + - | + "&&" + - | + name=$(nats request -s nats://$NATS_HOST:{{ .Values.nats.client.port }} name.test '' 2>/dev/null) + - | + "&&" + - | + [ $name = test ] + + restartPolicy: Never diff --git a/charts/mayastor/charts/nats/values.yaml b/charts/mayastor/charts/nats/values.yaml new file mode 100644 index 0000000..8812d58 --- /dev/null +++ b/charts/mayastor/charts/nats/values.yaml @@ -0,0 +1,827 @@ +############################### +# # +# NATS Server Configuration # +# # +############################### +nats: + image: + repository: nats + tag: 2.9.17-alpine + pullPolicy: IfNotPresent + # registry: docker.io + + # The servers name prefix, must be used for example when we want a NATS cluster + # spanning multiple Kubernetes clusters. + serverNamePrefix: "" + + # Server Tags + serverTags: + # - "foo" + # - "bar" + + # Sets GOMEMLIMIT environment variable which makes the Go GC be aware of memory limits + # from the container. Recommended to be set to about 90% of the resource memory limits. + # + # More info about the Go GC: https://go.dev/doc/gc-guide + # + # gomemlimit: "4GiB" + + # Toggle profiling. + # This enables nats-server pprof (profiling) port, so you can see goroutines + # stacks, memory heap sizes, etc. + profiling: + enabled: false + port: 6000 + + # Toggle using health check probes to better detect failures. + healthcheck: + # /healthz health check endpoint was introduced in NATS Server 2.7.1 + # Attempt to detect /healthz support by inspecting if tag is >=2.7.1 + detectHealthz: true + # Enable /healthz startupProbe for controlled upgrades of NATS JetStream + enableHealthz: true + # Enable /healthz liveness and readiness probes (supported in >=2.9.0) + # This is a feature flag and will be removed in future releases + enableHealthzLivenessReadiness: false + + # Enable liveness checks. If this fails, then the NATS Server will restarted. + liveness: + enabled: true + + initialDelaySeconds: 10 + timeoutSeconds: 5 + # NOTE: liveness check + terminationGracePeriodSeconds can introduce unnecessarily long outages + # due to the coupling between liveness probe and terminationGracePeriodSeconds. + # To avoid this, we make the periodSeconds of the liveness check to be about half the default + # time that it takes for lame duck graceful stop. + # + # In case of using Kubernetes +1.22 with probe-level terminationGracePeriodSeconds + # we could revise this but for now keep a minimal liveness check. + # + # More info: + # + # https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#probe-level-terminationgraceperiodseconds + # https://github.com/kubernetes/kubernetes/issues/64715 + # + periodSeconds: 30 + successThreshold: 1 + failureThreshold: 3 + + # Override the health check path + # httpGet: + # path: /healthz?js-enabled=true + + # Only for Kubernetes +1.22 that have pod level probes enabled. + # terminationGracePeriodSeconds: 5 + + # Periodically check for the server to be ready for connections while + # the NATS container is running. + readiness: + enabled: true + + initialDelaySeconds: 10 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + + # Override the health check path + # httpGet: + # path: /healthz?js-server-only=true + + # Enable startup checks to confirm server is ready for traffic. + # This is recommended for JetStream deployments since in cluster mode + # it will try to ensure that the server is ready to serve streams. + startup: + enabled: true + + initialDelaySeconds: 10 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 90 + + # Override the health check path + # httpGet: + # path: /healthz + + ## hostNetwork + hostNetwork: false + + ## Pod Dns Policy. Default is ClusterFirst + ## ref: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy + dnsPolicy: ClusterFirst + + # Adds a hash of the ConfigMap as a pod annotation + # This will cause the StatefulSet to roll when the ConfigMap is updated + configChecksumAnnotation: true + + # securityContext for the nats container + securityContext: {} + + # Toggle whether to enable external access. + # This binds a host port for clients, gateways and leafnodes. + externalAccess: false + + # Toggle to disable client advertisements (connect_urls), + # in case of running behind a load balancer + # it might be required to disable advertisements. + advertise: true + + # In case both external access and advertise are enabled + # then a service account would be required to be able to + # gather the public ip from a node. + serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + + # Toggle whether to automatically mount Service Account token in the pod + # not set means default value, boolean true/false overrides default value + # automountServiceAccountToken: true + + # The number of connect attempts against discovered routes. + connectRetries: 120 + + # selector matchLabels for the server and service. + # If left empty defaults are used. + # This is helpful if you are updating from Chart version <=7.4 + selectorLabels: {} + + # Resources to add to the container + # ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: {} + + client: + port: 4222 + portName: "client" + + # extraEnv is the list of environment variables to add to the nats-server container + extraEnv: [] + + # Server settings. + limits: + maxConnections: + maxSubscriptions: + maxControlLine: + maxPayload: + + writeDeadline: + maxPending: + maxPings: + + # How many seconds should pass before sending a PING + # to a client that has no activity. + pingInterval: + + # grace period after pod begins shutdown before starting to close client connections + lameDuckGracePeriod: "10s" + + # duration over which to slowly close close client connections after lameDuckGracePeriod has passed + lameDuckDuration: "30s" + + # terminationGracePeriodSeconds determines how long to wait for graceful shutdown + # this should be at least `lameDuckGracePeriod` + `lameDuckDuration` + 20s shutdown overhead + terminationGracePeriodSeconds: 60 + + logging: + debug: + trace: + logtime: + connectErrorReports: + reconnectErrorReports: + + # customConfigSecret can be used to use an custom secret for the config + # of the NATS Server. + # NOTE: For this to work the name of the configuration has to be + # called `nats.conf`. + # + # e.g. kubectl create secret generic custom-nats-conf --from-file nats.conf + # + # customConfigSecret: + # name: + # + # Alternately, the generated config can be extended with extra imports using the below syntax. + # The benefit of this is that cluster settings can be built up via helm values, but external + # secrets can be referenced and imported alongside it. + # + # config: + # : + # + # name: "" + # + # e.g: + # + # config: + # - name: ssh-key + # secret: + # secretName: ssh-key + # - name: config-vol + # configMap: + # name: log-config + + # mappings is used to configure subject mapping + # https://docs.nats.io/running-a-nats-service/configuration/configuring_subject_mapping + # e.g: + # mappings: + # foo: bar + # foo.cluster.scoped: + # - destination: bar.cluster.scoped + # weight: 70% + # cluster: us-west-1 + # - destination: foobar.cluster.scoped + # weight: 30% + # cluster: us-east-1 + mappings: {} + + jetstream: + enabled: false + + # Jetstream Domain + domain: + + # Jetstream Unique Tag prevent placing a stream in the same availability zone twice. + uniqueTag: + + max_outstanding_catchup: + + ########################## + # # + # Jetstream Encryption # + # # + ########################## + encryption: + # Use key if you want to provide the key via Helm Values + # key: random_key + + # Use a secret reference if you want to get a key from a secret + # secret: + # name: "nats-jetstream-encryption" + # key: "key" + + # Use cipher if you want to choose a different cipher from the default. + # cipher: aes + + ############################# + # # + # Jetstream Memory Storage # + # # + ############################# + memStorage: + enabled: true + size: 1Gi + + ############################ + # # + # Jetstream File Storage # + # # + ############################ + fileStorage: + enabled: true + storageDirectory: /data + + # Set for use with existing PVC + # existingClaim: jetstream-pvc + # claimStorageSize: 10Gi + + # Use below block to create new persistent volume + # only used if existingClaim is not specified + size: 10Gi + # storageClassName: "" + accessModes: + - ReadWriteOnce + annotations: + # key: "value" + + # Use below if fileStorage is not enabled but you are persisting + # data using an alternative to PVC (e.g. hostPath) + # These set the corresponding jetstream configuration in nats.conf. + # store_dir: "/data" + # max_file: "10Gi" + + ####################### + # # + # TLS Configuration # + # # + ####################### + # + # # You can find more on how to setup and trouble shoot TLS connnections at: + # + # # https://docs.nats.io/nats-server/configuration/securing_nats/tls + # + + # tls: + # allowNonTLS: false + # secret: + # name: nats-client-tls + # ca: "ca.crt" + # cert: "tls.crt" + # key: "tls.key" + +mqtt: + enabled: false + ackWait: 1m + maxAckPending: 100 + + ####################### + # # + # TLS Configuration # + # # + ####################### + # + # # You can find more on how to setup and trouble shoot TLS connnections at: + # + # # https://docs.nats.io/nats-server/configuration/securing_nats/tls + # + + # + # tls: + # secret: + # name: nats-mqtt-tls + # ca: "ca.crt" + # cert: "tls.crt" + # key: "tls.key" + +nameOverride: "" +namespaceOverride: "" + +# An array of imagePullSecrets, and they have to be created manually in the same namespace +# ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] + +# Toggle whether to use setup a Pod Security Context +# ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +securityContext: {} +# securityContext: +# fsGroup: 1000 +# runAsUser: 1000 +# runAsNonRoot: true + +# Affinity for pod assignment +# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +affinity: {} + +## Pod priority class name +## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass +priorityClassName: null + +# Service topology +# ref: https://kubernetes.io/docs/concepts/services-networking/service-topology/ +topologyKeys: [] + +# Pod Topology Spread Constraints +# ref https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +topologySpreadConstraints: [] +# - maxSkew: 1 +# topologyKey: zone +# whenUnsatisfiable: DoNotSchedule + +# Annotations to add to the NATS pods +# ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +podAnnotations: {} +# key: "value" + +# Define a Pod Disruption Budget for the stateful set +# ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ +podDisruptionBudget: + enabled: true + maxUnavailable: 1 + # minAvailable: 1 + +# Node labels for pod assignment +# Ref: https://kubernetes.io/docs/user-guide/node-selection/ +nodeSelector: {} + +# Node tolerations for server scheduling to nodes with taints +# Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +# +tolerations: [] +# - key: "key" +# operator: "Equal|Exists" +# value: "value" +# effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + +# Annotations to add to the NATS StatefulSet +statefulSetAnnotations: {} + +# Labels to add to the pods of the NATS StatefulSet +statefulSetPodLabels: {} + +# Annotations to add to the NATS Service +serviceAnnotations: {} + +# additionalContainers are the sidecar containers to add to the NATS StatefulSet +additionalContainers: [] + +# additionalVolumes are the additional volumes to add to the NATS StatefulSet +additionalVolumes: [] + +# additionalVolumeMounts are the additional volume mounts to add to the nats-server and nats-server-config-reloader containers +additionalVolumeMounts: [] + +cluster: + enabled: false + replicas: 3 + noAdvertise: false + + # Explicitly set routes for clustering. + # When JetStream is enabled, the serverName must be unique in the cluster. + extraRoutes: [] + + # authorization: + # user: foo + # password: pwd + # timeout: 0.5 + +# Leafnode connections to extend a cluster: +# +# https://docs.nats.io/nats-server/configuration/leafnodes +# +leafnodes: + enabled: false + port: 7422 + noAdvertise: false + # remotes: + # - url: "tls://connect.ngs.global:7422" + + ####################### + # # + # TLS Configuration # + # # + ####################### + # + # # You can find more on how to setup and trouble shoot TLS connnections at: + # + # # https://docs.nats.io/nats-server/configuration/securing_nats/tls + # + + # + # tls: + # secret: + # name: nats-client-tls + # ca: "ca.crt" + # cert: "tls.crt" + # key: "tls.key" + +# Gateway connections to create a super cluster +# +# https://docs.nats.io/nats-server/configuration/gateways +# +gateway: + enabled: false + port: 7522 + name: "default" + # authorization: + # user: foo + # password: pwd + # timeout: 0.5 + # rejectUnknownCluster: false + + # You can add an implicit advertise address instead of using from Node's IP + # could also be a fqdn address + # advertise: "nats.example.com" + + ############################# + # # + # List of remote gateways # + # # + ############################# + # gateways: + # - name: other + # url: nats://my-gateway-url:7522 + + ####################### + # # + # TLS Configuration # + # # + ####################### + # + # # You can find more on how to setup and trouble shoot TLS connnections at: + # + # # https://docs.nats.io/nats-server/configuration/securing_nats/tls + # + # tls: + # secret: + # name: nats-client-tls + # ca: "ca.crt" + # cert: "tls.crt" + # key: "tls.key" + +# In case of both external access and advertisements being +# enabled, an initializer container will be used to gather +# the public ips. +bootconfig: + image: + repository: natsio/nats-boot-config + tag: 0.10.1 + pullPolicy: IfNotPresent + # registry: docker.io + + securityContext: {} + + # Resources to add to the container + # ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: {} + +# NATS Box +# +# https://github.com/nats-io/nats-box +# +natsbox: + enabled: true + image: + repository: natsio/nats-box + tag: 0.13.8 + pullPolicy: IfNotPresent + # registry: docker.io + + securityContext: {} + + # Resources to add to the container + # ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: {} + + # Annotations to add to the natsbox deployment + # ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + annotations: {} + # key: "value" + + # Labels to add to the natsbox deployment + # ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + additionalLabels: {} + + # An array of imagePullSecrets, and they have to be created manually in the same namespace + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + imagePullSecrets: [] + # - name: dockerhub + + # credentials: + # secret: + # name: nats-sys-creds + # key: sys.creds + + # Annotations to add to the box pods + # ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + podAnnotations: {} + # key: "value" + + # Labels to add to the box pods + # ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + podLabels: {} + # key: "value" + + # Affinity for nats box pod assignment + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + affinity: {} + + # Node labels for pod assignment + # Ref: https://kubernetes.io/docs/user-guide/node-selection/ + nodeSelector: {} + + # Node tolerations for server scheduling to nodes with taints + # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + # + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + # Additional nats-box server Volume mounts + extraVolumeMounts: [] + + # Additional nats-box server Volumes + extraVolumes: [] + + # Toggle whether to automatically mount Service Account token in the pod + # not set means default value, boolean true/false overrides default value + # automountServiceAccountToken: true + +# The NATS config reloader image to use. +reloader: + enabled: true + image: + repository: natsio/nats-server-config-reloader + tag: 0.10.1 + pullPolicy: IfNotPresent + # registry: docker.io + + securityContext: {} + + # Resources to add to the container + # ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: {} + + extraConfigs: [] + +# Prometheus NATS Exporter configuration. +exporter: + enabled: true + image: + repository: natsio/prometheus-nats-exporter + tag: 0.11.0 + pullPolicy: IfNotPresent + # registry: docker.io + + portName: metrics + securityContext: {} + + # Resources to add to the container + # ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: {} + + # override the default args passed to the exporter + # see https://github.com/nats-io/prometheus-nats-exporter#usage + # make sure to pass HTTP monitoring port URL as last arg, e.g ["-connz", "http://localhost:8222/"] + args: [] + # Prometheus operator ServiceMonitor support. Exporter has to be enabled + serviceMonitor: + enabled: false + ## Specify the namespace where Prometheus Operator is running + ## + # namespace: monitoring + labels: {} + annotations: {} + path: /metrics + # interval: + # scrapeTimeout: + +# Authentication setup +auth: + enabled: false + + # basic: + # noAuthUser: + # # List of users that can connect with basic auth, + # # that belong to the global account. + # users: + + # defaultPermissions: + # publish: ["SANDBOX.*"] + # subscribe: ["SANDBOX.>"] + + # # List of accounts with users that can connect + # # using basic auth. + # accounts: + + # Reference to the Operator JWT. + # operatorjwt: + # configMap: + # name: operator-jwt + # key: KO.jwt + + # Token authentication + # token: + + # NKey authentication + # nkeys: + # users: + + # Public key of the System Account + # systemAccount: + + resolver: + # Disables the resolver by default + type: none + + ########################################## + # # + # Embedded NATS Account Server Resolver # + # # + ########################################## + # type: full + + # If the resolver type is 'full', delete when enabled will rename the jwt. + allowDelete: false + + # Interval at which a nats-server with a nats based account resolver will compare + # it's state with one random nats based account resolver in the cluster and if needed, + # exchange jwt and converge on the same set of jwt. + interval: 2m + + # Operator JWT + operator: + + # System Account Public NKEY + systemAccount: + + # resolverPreload: + # : + + # Directory in which the account JWTs will be stored. + store: + dir: "/accounts/jwt" + + # Size of the account JWT storage. + size: 1Gi + + # StorageClass of JWT storage claim. + # storageClassName: "" + + ############################## + # # + # Memory resolver settings # + # # + ############################## + # type: memory + # + # Use a configmap reference which will be mounted + # into the container. + # + # configMap: + # name: nats-accounts + # key: resolver.conf + + ########################## + # # + # URL resolver settings # + # # + ########################## + # type: URL + # url: "http://nats-account-server:9090/jwt/v1/accounts/" + +websocket: + enabled: false + port: 443 + noTLS: true + + sameOrigin: false + allowedOrigins: [] + + # This will optionally specify what host:port for websocket + # connections to be advertised in the cluster. + # advertise: "host:port" + + # Set the handshake timeout for websocket connections + # handshakeTimeout: 5s + +# Network Policy configuration +networkPolicy: + enabled: false + # Don't require client label for connections + # When set to false, only pods with the correct client label will have network access to the ports + # NATS is listening on. When true, NATS will accept connections from any source + # (with the correct destination port). + allowExternal: true + # Add extra ingress rules to the NetworkPolicy + # e.g: + # extraIngress: + # - ports: + # - port: 1234 + # from: + # - podSelector: + # - matchLabels: + # - role: frontend + # - podSelector: + # - matchExpressions: + # - key: role + # operator: In + # values: + # - frontend + extraIngress: [] + # Add extra ingress rules to the NetworkPolicy + # e.g: + # extraEgress: + # - ports: + # - port: 1234 + # to: + # - podSelector: + # - matchLabels: + # - role: frontend + # - podSelector: + # - matchExpressions: + # - key: role + # operator: In + # values: + # - frontend + extraEgress: [] + # Labels to match to allow traffic from other namespaces + ingressNSMatchLabels: {} + # Pod labels to match to allow traffic from other namespaces + ingressNSPodMatchLabels: {} + +# Cluster Domain configured on the kubelets +# https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/ +k8sClusterDomain: cluster.local + +# Define if NATS is using FQDN name for clustering (i.e. nats-0.nats.default.svc.cluster.local) or short name (i.e. nats-0.nats.default). +useFQDN: true + +# Add labels to all the deployed resources +commonLabels: {} + +# podManagementPolicy controls how pods are created during initial scale up, +# when replacing pods on nodes, or when scaling down. +podManagementPolicy: Parallel + +# Shared volume to be mounted in pods for pid +pidVolume: + emptyDir: {} + +# Shared volume to be mounted in pods for advertiseconfig +advertiseconfigVolume: + emptyDir: {} diff --git a/charts/mayastor/doc.yaml b/charts/mayastor/doc.yaml new file mode 100644 index 0000000..addde3f --- /dev/null +++ b/charts/mayastor/doc.yaml @@ -0,0 +1,19 @@ +project: + name: OpenEBS Mayastor + shortName: Mayastor + url: https://openebs.io/mayastor + description: Fast NVMe backed storage for enterprise users on Kubernetes +repository: + url: https://openebs.github.io/mayastor-extensions/ + name: mayastor +chart: + name: mayastor + version: 2.10.0 + values: "-- generate from values file --" + valuesExample: "-- generate from values file --" +prerequisites: + - "Kubernetes v1.21+" + - Linux Kernel 5.4+ on Worker Nodes with required nvme modules loaded +release: + name: mayastor + namespace: mayastor diff --git a/charts/mayastor/label-etcd-for-helm-release.sh b/charts/mayastor/label-etcd-for-helm-release.sh new file mode 100644 index 0000000..d0e0ebf --- /dev/null +++ b/charts/mayastor/label-etcd-for-helm-release.sh @@ -0,0 +1,322 @@ +#!/usr/bin/env sh + +# This script was introduced in v2.10.0, to upgrade the 'etcd' dependency helm chart from 8.6.0 to 12.0.14. +# The etcd chart, in v8.6.0, used to have a podAntiAffinity section which looked like this, when used with +# the 'hard' podAntiAffinityPreset.. +# +# podAntiAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# - labelSelector: +# matchLabels: +# app.kubernetes.io/instance: mayastor +# app.kubernetes.io/name: etcd +# topologyKey: kubernetes.io/hostname +# +# v9.0.0 introduced a new label, 'app.kubernetes.io/component: etcd'. This was put into the StatefulSet labels, +# the .spec.selector, the PodSpec labels, and the podAntiAffinity section. So, v9.0.0 onwards, this is what the +# podAntiAffinity labels look like.. +# +# matchLabels: +# app.kubernetes.io/component: etcd +# app.kubernetes.io/instance: mayastor +# app.kubernetes.io/name: etcd +# +# The instructions to upgrade to v9.0.0 were as follows -- +# 1. Label the Etcd Pods with the new label +# 2. Delete the Etcd StatefulSet with the `--cascade=orphan` on the the kubectl binary +# 3. Helm upgrade +# Step 2 was necessary because StatefulSet selectors and affinity are immutable. The idea is that we delete the +# StatefulSet, leaving the Pods behind. We add the new label to the Pods (1) so that the new StatefulSet can find +# them using the new set of selector labels. We run `helm upgrade` and the new StatefulSet comes up and reclaims the +# Pods. Then it uses its StatefulSet rollout strategy to bring down the Pods one-by-one and update their affinity. +# Because of the orphan cascade option, the Pods don't come down all at once and there is no full blown downtime. +# +# v11.0.0 introduces a pre-upgrade Job hook on the Etcd chart. The podAntiAffinity on the pre-upgrade Job Pods uses the +# 'soft' podAntiAffinityPreset and so it is not of much concern to us. The Job Pods are stateless and they don't need +# the podAntiAffinity w.r.t. the Etcd StatefulSet Pods. The labels on the Job Pods look like this.. +# +# labels: +# app.kubernetes.io/component: etcd-pre-upgrade-job +# app.kubernetes.io/instance: mayastor +# app.kubernetes.io/name: etcd +# .. +# +# What stands out here is that the Job Pods don't match the criteria for podAntiAffinity of the v11.x Etcd chart, but +# they meet the criteria for the Etcd charts < v9.0.0. This means that to successfully upgrade to a v11.x or newer +# chart, Mayastor users would require at least one extra node, where they don't have any Etcd Pod scheduled. +# +# But, that's easily fixable with the v9.0.0 upgrade steps.. we label the Pods, we delete the StatefulSet and orphan the +# Pods, and after helm upgrade the new StatefulSet comes up and fixes everything, right? No! The new StatefulSet gets +# to come up only after the Etcd pre-upgrade Job is through. And for users for whom, no. of nodes == Etcd replicas, +# and they're on v8.6.0, they can't get the pre-upgrade Job to schedule. So, they can only fix podAntiAffinity w.r.t. +# the pre-upgrade Job after the pre-upgrade Job has been scheduled and has run to completion. +# +# The solution for this problem, on this script, is to grab the existing 8.6.0 Etcd StatefulSet object, plug the labels +# in, set the cluster env to join an existing cluster. Then we follow the usual v9.x-like flow, we label the Pods and +# delete the StatefulSet, while orphaning the Pods. Then we re-create the labelled StatefulSet. The new 8.6.0 +# StatefulSet's rollout controller will fix the affinity on the Pods one-by-one and bring them up. All of this happens +# as a part of a Mayastor chart pre-upgrade Job, which runs before the Etcd one. And then the Etcd Job schedules easy +# peasy. Success! + +set -o errexit + +# Write output to stdout. +# Arguments: +# $1 -- Message +# Returns: +# None +log() { + echo "${1}" +} + +# Write log output along with Kubernetes Namespace, if any. +# Arguments: +# $1 -- Message +# $2 -- Namespace (optional) +# Returns: +# None +log_with_ns() { + message="$1" + namespace="${2:-$NAMESPACE}" + + printf "%s" "$message" + if [ -n "$namespace" ]; then + printf ", in namespace %s" "$namespace" + fi + + # final newline + printf '\n' +} + +# Write output to stderr output stream. +# Arguments: +# $1 -- Message +# Returns: +# None +log_to_stderr() { + echo "${1}" >&2 +} + +# Print log message as an error message. +# Arguments: +# $1 -- Output message +# Returns: +# None +log_error() { + log_to_stderr "ERROR: $1" +} + +# Exit with error status and print error. +# Arguments: +# $1 -- Output message +# $2 -- Exit code (default: 1) +# Returns: +# None +log_fatal() { + _return="${2:-1}" + log_error "$1" + exit "${_return}" +} + +# Print the help text for this script. +# Arguments: +# None +# Returns: +# None +print_help() { + cat < + + (required) The release name of the helm + release whose Etcd + +Options: + -h, --help Display this text. + -n, --namespace Set the kubernetes namespace of the Etcd + cluster. (default: ) + +Examples: + $0 -n mayastor openebs-mayastor +EOF +} + +# Parse inputs to this script. +# Arguments: +# $@ -- Shell args +# Returns: +# None +parse_args() { + while test "$#" -gt 0; do + arg="$1" + case "$arg" in + --) + shift + break + ;; + -n* | --namespace*) + case "$arg" in + -n | --namespace) + test $# -lt 2 && log_fatal "missing value for the optional argument '$arg'." + NAMESPACE=$2 + shift + ;; + *) + NAMESPACE=${arg#*=} + ;; + esac + ;; + -h* | --help*) + print_help + exit 0 + ;; + -*) + print_help + log_fatal "unexpected argument '$arg'" + ;; + *) + if [ -z "$RELEASE_NAME" ]; then + RELEASE_NAME=$arg + else + print_help + log_fatal "unexpected extra argument '$arg'" + fi + ;; + esac + shift + done + + # Handling args after the "--". + for arg; do + if [ -z "$RELEASE_NAME" ]; then + RELEASE_NAME=$arg + else + print_help + log_fatal "unexpected extra argument: '$arg'" + fi + done + + # Handling missing arguments. + if [ -z "$RELEASE_NAME" ]; then + print_help + log_fatal "missing required " + fi +} + +# Run kubectl with namespace arg, if any. +# Arguments: +# kubectl command arguments and options related to namespaced resources +# Returns: +# kubectl command outout +kubectl_ns() { + if [ -n "$NAMESPACE" ]; then + "$KUBECTL" -n "$NAMESPACE" "$@" + else + "$KUBECTL" + fi +} + +# Count the no. of newlines in a string. +# Arguments: +# $1 -- The string to count newlines from +# Returns: +# Count of newlines in the string +line_count() { + [ -n "$1" ] && printf "%s\n" "$1" | wc -l | sed 's/^[[:space:]]*//' || echo 0 +} + +# Prints the Yaml to an Etcd StatefulSet +# Arguments: +# $1 -- Kubernetes label selector for the Etcd StatefulSet +# Returns: +# Etcd StatefulSet YAML +get_etcd_sts_yaml_or_die() { + etcd_selector=$1 + + sts_name="$(kubectl_ns get sts -l "${etcd_selector}" \ +-o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')" || exit $? + + # Make sure that there's just one such StatefulSet. + name_count=$(line_count "$sts_name") + if [ "$name_count" -eq 0 ]; then + log_with_ns "Nothing to do: no such StatefulSet" + exit 0 + elif [ "$name_count" -gt 1 ]; then + log_fatal "$(log_with_ns "expected 1 but found $name_count StatefulSets: $sts_name")" + fi + + EXISTING_ETCD_STS="$(kubectl_ns get sts "$sts_name" -o yaml)" +} + +# ============================================================================= + +KUBECTL="kubectl" +NAMESPACE= +# Mandatory input. +RELEASE_NAME= +EXISTING_ETCD_STS= + +parse_args "$@" + +# The 'app.kubernetes.io/component!=etcd' selector makes sure we're not picking up a StatefulSet +# which already has the label. +# The 'helm.sh/chart=etcd-8.6.0' selector makes sure we get 8.6.0 and nothing else. +etcd_selector="app.kubernetes.io/name=etcd,\ +app.kubernetes.io/instance=${RELEASE_NAME},\ +helm.sh/chart=etcd-8.6.0,\ +app.kubernetes.io/component!=etcd" + +# This step needs to happen in the outer scope of this script, so that it's able to exit when it fails. +# This will exit 0 if there is no StatefulSet of 8.6.0 and w/o the label. This makes the create step idempotent. +get_etcd_sts_yaml_or_die "$etcd_selector" + +# This step does these few things.. +# - Add 'app.kubernetes.io/component: etcd' to .metadata.labels +# - Add 'app.kubernetes.io/component: etcd' to .spec.selector +# - Add 'app.kubernetes.io/component: etcd' to the PodSpec's .metadata.labels +# - Add 'app.kubernetes.io/component: etcd' to podAntiAffinity's matchLabels +# - Change the value of ETCD_INITIAL_CLUSTER_STATE to 'existing' +modified_etcd_yaml="$(echo "$EXISTING_ETCD_STS" | \ +awk -v label="app.kubernetes.io/component: etcd" \ + -v init_state='value: "existing"' ' + # As soon as we hit "status:", stop processing. + /^[[:space:]]*status:/ { exit } + + # If pending==1, this is the line after ETCD_INITIAL_CLUSTER_STATE. + pending { + print indent " " init_state + pending = 0 + next + } + + # Match the name=etcd label, capture indent, insert component label line. + $0 ~ /^[[:space:]]*app\.kubernetes\.io\/name: etcd$/ { + match($0, /^[[:space:]]*/) + prefix = substr($0, RSTART, RLENGTH) + print + print prefix label + next + } + + # Match the ETCD_INITIAL_CLUSTER_STATE entry, capture indent, + # and mark pending so we replace the next line. + $0 ~ /^[[:space:]]*- name: ETCD_INITIAL_CLUSTER_STATE/ { + match($0, /^[[:space:]]*/) + indent = substr($0, RSTART, RLENGTH) + print + pending = 1 + next + } + + # All other lines pass through unchanged. + { print } +')" || exit $? + +set -o xtrace +# Label the Etcd StatefulSet Pods. This step is idempotent all by itself. +kubectl_ns label --overwrite po -l "$etcd_selector" app.kubernetes.io/component=etcd +# Delete the StatefulSet, leaving the Pods behind. The --ignore-not-found makes the delete step idempotent. +kubectl_ns delete sts -l "$etcd_selector" --cascade=orphan --ignore-not-found +# Create the StatefulSet with the new label. This is idempotent because we exit early if we find no StatefulSet. +echo "$modified_etcd_yaml" | "$KUBECTL" create -f - + +set +o errexit +o xtrace diff --git a/charts/mayastor/loki-storage.md b/charts/mayastor/loki-storage.md new file mode 100644 index 0000000..724e539 --- /dev/null +++ b/charts/mayastor/loki-storage.md @@ -0,0 +1,101 @@ +# Loki Storage Options Documentation + +## Introduction + +Loki provides flexible storage options depending on your deployment needs. Below is a summary of how to configure and choose the appropriate storage based on your specific deployment scenario, including filesystem volumes, object storage, and external S3-compatible solutions. + +--- + +### 1. **Single Replica Deployment (Filesystem Volume)** + +When deploying **Loki as a single replica**, you can use a **filesystem volume** for storage. This is a simple and cost-effective option for single-instance setups where high availability and scalability are not required. + +- **Recommended for**: Small-scale deployments or testing environments where high availability (HA) is not a concern. + +Below is an example to use a filesystem volume with single replica loki. + +```yaml + loki: + enabled: true + + loki: + schemaConfig: + configs: + - from: 2024-04-01 + store: tsdb + object_store: filesystem + schema: v13 + index: + prefix: loki_index_ + period: 24h + commonConfig: + replication_factor: 1 + storage: + type: filesystem + + singleBinary: + replicas: 1 + drivesPerNode: 1 + persistence: + enabled: true + + minio: + enabled: false +``` + +--- + +### 2. **High Availability (HA) Deployment (Object Storage)** + +For **HA (High Availability)** deployments, **object storage** is **mandatory**. This ensures that your logs are replicated and highly available across multiple nodes, reducing the risk of data loss and providing fault tolerance. + +- **Recommended for**: Production environments with multiple Loki instances, where high availability and horizontal scaling are required. + +By default with openebs loki is deployed in this mode, i.e with multiple replicas and with a minio distributed object storage. + +--- + +### 3. **MinIO as the Default Object Storage** + +By default, **MinIO** is used as the object storage backend for Loki. MinIO can run in both **single replica** and **HA (High Availability)** modes. However, if you are deploying Loki in an HA configuration, it is **recommended to use MinIO in HA mode** along with HA Loki for optimal performance and scalability. + +- **MinIO in HA mode** is suitable for high availability, fault tolerance, and ensuring your data remains consistent across multiple Loki replicas. + +--- + +### 4. **Migrating from Filesystem Volume to Object Storage** + +If you start with **Loki as a single replica** using a filesystem volume and later decide to scale up to an HA deployment, **it is crucial to start with object storage from the beginning**. Migrating from a filesystem volume to object storage after the initial setup is **not easily possible** and could involve complex data migration steps. + +- **Recommendation**: Start with object storage (such as MinIO or another S3-compatible solution) if you plan to scale your deployment in the future. + +--- + +### 5. **Using External S3-Compatible Storage** + +If you prefer not to use **MinIO** as the object storage solution for Loki, you can configure an **external S3-compatible** storage backend. You can use any S3-compatible service, such as AWS S3, Google Cloud Storage, or other object storage services that support the S3 API. + +To configure Loki to use an external S3 bucket, update your Loki configuration as follows: + +```yaml +# Configure these if you don't want to use MinIO and rather an external S3 bucket. +loki: + loki: + storage: + type: s3 + bucketNames: + chunks: # Define your S3 bucket name for chunks storage + s3: + s3: s3://:@/ # S3 URL with credentials and endpoint + endpoint: # Endpoint for your external S3-compatible service + region: # Region of your S3 bucket + secretAccessKey: # Access key for your S3-compatible service + accessKeyId: # Secret key for your S3-compatible service + object_store: + type: s3 + s3: + endpoint: s3://:@/ # S3 URL with credentials and endpoint + region: # Region of your external S3-compatible storage + access_key_id: # Your S3 access key ID + secret_access_key: # Your S3 secret access key +``` \ No newline at end of file diff --git a/charts/mayastor/product.yaml b/charts/mayastor/product.yaml new file mode 100644 index 0000000..ca39e4b --- /dev/null +++ b/charts/mayastor/product.yaml @@ -0,0 +1,4 @@ +name: Mayastor +project: OpenEBS +domain: openebs.io +imagePrefix: mayastor diff --git a/charts/mayastor/templates/NOTES.txt b/charts/mayastor/templates/NOTES.txt new file mode 100644 index 0000000..66576e2 --- /dev/null +++ b/charts/mayastor/templates/NOTES.txt @@ -0,0 +1,4 @@ +OpenEBS Mayastor has been installed. Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +For more information or to view the documentation, visit our website at https://openebs.io/docs/. diff --git a/charts/mayastor/templates/_helpers.tpl b/charts/mayastor/templates/_helpers.tpl new file mode 100644 index 0000000..5f5917b --- /dev/null +++ b/charts/mayastor/templates/_helpers.tpl @@ -0,0 +1,389 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Renders a value that contains template. +Usage: +{{ include "render" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define "render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} + +{{/* +Renders the CORE server init container, if enabled +Usage: +{{ include "base_init_core_containers" . }} +*/}} +{{- define "base_init_core_containers" -}} + {{- if .Values.base.initCoreContainers.enabled }} + {{- include "render_init_containers" (dict "value" .Values.base.initCoreContainers.containers "context" $) | nindent 8 }} + {{- end }} +{{- end -}} + +{{/* +Renders the HA NODE AGENT init container, if enabled +Usage: +{{ include "base_init_ha_node_containers" . }} +*/}} +{{- define "base_init_ha_node_containers" -}} + {{- if .Values.base.initHaNodeContainers.enabled }} + {{- include "render_init_containers" (dict "value" .Values.base.initHaNodeContainers.containers "context" $) | nindent 8 }} + {{- end }} +{{- end -}} + +{{/* +Renders the base init containers for all deployments, if any +Usage: +{{ include "base_init_containers" . }} +*/}} +{{- define "base_init_containers" -}} + {{- if .Values.base.initContainers.enabled }} + {{- include "render_init_containers" (dict "value" .Values.base.initContainers.containers "context" $) | nindent 8 }} + {{- end }} + {{- include "jaeger_collector_init_container" . }} +{{- end -}} + +{{/* +Renders the jaeger agent init container, if enabled +Usage: +{{ include "jaeger_collector_init_container" . }} +*/}} +{{- define "jaeger_collector_init_container" -}} + {{- if .Values.base.jaeger.enabled }} + {{- if .Values.base.jaeger.initContainer }} + {{- if .Values.base.jaeger.collector }} + {{- include "render_init_containers" (dict "value" .Values.base.jaeger.collector.initContainer "context" $) | nindent 8 }} + {{- else }} + - name: jaeger-probe + image: busybox:latest + command: [ 'sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 -u jaeger-collector:4317; do date; echo "Waiting for jaeger..."; sleep 1; done;' ] + {{- end }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Renders the csi node init containers, if enabled +Usage: +{{ include "csi_node_init_containers" . }} +*/}} +{{- define "csi_node_init_containers" -}} + {{- if (.Values.csi.node.initContainers).enabled }} + {{- include "render_init_containers" (dict "value" .Values.csi.node.initContainers.containers "context" $) | nindent 8 }} + {{- end }} +{{- end -}} + +{{/* +Renders the base image pull secrets for all deployments, if any +Usage: +{{ include "base_pull_secrets" . }} +*/}} +{{- define "base_pull_secrets" -}} + {{- if (not (empty .Values.image.pullSecrets)) }} + {{- range .Values.image.pullSecrets | uniq -}} + {{ nindent 8 "- name:" }} {{ . }} + {{- end }} + {{- else -}} + {{- if .Values.base.imagePullSecrets }} + {{- if .Values.base.imagePullSecrets.enabled }} + {{- if (empty .Values.base.imagePullSecrets.secrets) }} + {{ nindent 8 "- name: login" }} + {{- else -}} + {{- include "render" (dict "value" .Values.base.imagePullSecrets.secrets "context" $) | nindent 8 }} + {{- end}} + {{- end }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Renders the REST server init container, if enabled +Usage: +{{- include "rest_agent_init_container" . }} +*/}} +{{- define "rest_agent_init_container" -}} + {{- if .Values.base.initRestContainer.enabled }} + {{- include "render_init_containers" (dict "value" .Values.base.initRestContainer.initContainer "context" $) | nindent 8 }} + {{- end }} +{{- end -}} + +{{/* +Renders the jaeger scheduling rules, if any +Usage: +{{ include "jaeger_scheduling" . }} +*/}} +{{- define "jaeger_scheduling" -}} + {{- if index .Values "jaeger-operator" "affinity" }} + affinity: + {{- include "render" (dict "value" (index .Values "jaeger-operator" "affinity") "context" $) | nindent 4 }} + {{- end }} + {{- if index .Values "jaeger-operator" "tolerations" }} + tolerations: + {{- include "render" (dict "value" (index .Values "jaeger-operator" "tolerations") "context" $) | nindent 4 }} + {{- end }} +{{- end -}} + +{{/* Generate Core list specification (-l param of io-engine) */}} +{{- define "cpuFlag" -}} +{{- include "coreListUniq" . -}} +{{- end -}} + +{{/* Get the number of cores from the coreList */}} +{{- define "coreCount" -}} +{{- include "coreListUniq" . | split "," | len -}} +{{- end -}} + +{{- define "logFormat" -}} +{{- if (regexMatch "^((json|pretty|compact))$" .Values.base.logging.format) -}} + {{- print .Values.base.logging.format -}} +{{- else -}} + {{- fail "invalid logging format. valid values are json, pretty, compact" -}} +{{- end -}} +{{- end -}} + +{{/* Get a list of cores as a comma-separated list */}} +{{- define "coreListUniq" -}} +{{- if .Values.io_engine.coreList -}} +{{- $cores_pre := .Values.io_engine.coreList -}} +{{- if not (kindIs "slice" .Values.io_engine.coreList) -}} +{{- $cores_pre = list $cores_pre -}} +{{- end -}} +{{- $cores := list -}} +{{- range $index, $value := $cores_pre | uniq -}} +{{- $value = $value | toString | replace " " "" }} +{{- if eq ($value | int | toString) $value -}} +{{- $cores = append $cores $value -}} +{{- end -}} +{{- end -}} +{{- $first := first $cores | required (print "At least one core must be specified in io_engine.coreList") -}} +{{- $cores | join "," -}} +{{- else -}} +{{- if gt 1 (.Values.io_engine.cpuCount | int) -}} +{{- fail ".Values.io_engine.cpuCount must be >= 1" -}} +{{- end -}} +{{- untilStep 1 (add 1 .Values.io_engine.cpuCount | int) 1 | join "," -}} +{{- end -}} +{{- end }} + +{{/* +Adds the project domain to labels +Usage: +{{ include "label_prefix" . }}/release: {{ .Release.Name }} +*/}} +{{- define "label_prefix" -}} + {{ $product := .Files.Get "product.yaml" | fromYaml }} + {{- print $product.domain -}} +{{- end -}} + +{{/* +Creates the tolerations based on the global and component wise tolerations, with early eviction +Usage: +{{ include "_tolerations_with_early_eviction" (dict "template" . "localTolerations" .Values.path.to.local.tolerations) }} +*/}} +{{- define "_tolerations_with_early_eviction" -}} +{{- toYaml .template.Values.earlyEvictionTolerations | nindent 8 }} +{{- if .localTolerations }} + {{- toYaml .localTolerations | nindent 8 }} +{{- else if .template.Values.tolerations }} + {{- toYaml .template.Values.tolerations | nindent 8 }} +{{- end }} +{{- end }} + + +{{/* +Creates the tolerations based on the global and component wise tolerations +Usage: +{{ include "tolerations" (dict "template" . "localTolerations" .Values.path.to.local.tolerations) }} +*/}} +{{- define "tolerations" -}} +{{- if .localTolerations }} + {{- toYaml .localTolerations | nindent 8 }} +{{- else if .template.Values.tolerations }} + {{- toYaml .template.Values.tolerations | nindent 8 }} +{{- end }} +{{- end }} + +{{/* +Generates the priority class name, with the given `template` and the `localPriorityClass` +Usage: +{{ include "priority_class" (dict "template" . "localPriorityClass" .Values.path.to.local.priorityClassName) }} +*/}} +{{- define "priority_class" -}} + {{- if typeIs "string" .localPriorityClass }} + {{- if .localPriorityClass -}} + {{ printf "%s" .localPriorityClass -}} + {{- else if .template.Values.priorityClassName -}} + {{ printf "%s" .template.Values.priorityClassName -}} + {{- else -}} + {{ printf "" -}} + {{- end -}} + {{- end -}} +{{- end -}} + + +{{/* +Generates the priority class name, with the given `template` and the `localPriorityClass`, sets to mayastor default priority class +if both are empty +Usage: +{{ include "priority_class_with_default" (dict "template" . "localPriorityClass" .Values.path.to.local.priorityClassName) }} +*/}} +{{- define "priority_class_with_default" -}} + {{- if typeIs "string" .localPriorityClass }} + {{- if .localPriorityClass -}} + {{ printf "%s" .localPriorityClass -}} + {{- else if .template.Values.priorityClassName -}} + {{ printf "%s" .template.Values.priorityClassName -}} + {{- else -}} + {{ printf "%s-cluster-critical" .template.Release.Name -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* + Generate the default StorageClass parameters. + This is required because StorageClass parameters cannot be patched after creation. + If the StorageClass already exists, the default StorageClass carries the parameters and values + of that StorageClass. Else, it carries the default parameters and values. +*/}} +{{- define "storageClass.parameters" -}} + {{- $scName := index . 0 -}} + {{- $valuesParams := index . 1 -}} + + {{/* Check to see if a default StorageClass already exists */}} + {{- $sc := lookup "storage.k8s.io/v1" "StorageClass" "" $scName -}} + + {{- if $sc -}} + {{/* Existing defaults */}} + {{ range $param, $val := $sc.parameters }} +{{ $param | quote }}: {{ $val | quote }} + {{- end -}} + + {{- else -}} + {{/* Current defaults */}} + {{ range $param, $val := $valuesParams }} +{{ $param | quote }}: {{ $val | quote }} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Adds the image prefix to image name +*/}} +{{- define "image_prefix" -}} + {{ $product := .Files.Get "product.yaml" | fromYaml }} + {{- print $product.imagePrefix -}} +{{- end -}} + +{{/* +Get the Jaeger URL +*/}} +{{- define "jaeger_url" -}} + {{- if $collector := .Values.base.jaeger.collector }} + {{- $collector.name }}:{{ $collector.port }} + {{- else }} + {{- print "jaeger-collector:4317" -}} + {{- end }} +{{- end -}} + +{{/* + Create a normalized etcd name based on input parameters + */}} +{{- define "etcdUrl" -}} + {{- if eq (.Values.etcd.enabled) false }} + {{- if .Values.etcd.externalUrl }} + {{- .Values.etcd.externalUrl }} + {{- else }} + {{- fail "etcd.externalUrl must be set" }} + {{- end }} + {{- else }} + {{- .Release.Name }}-etcd:{{ .Values.etcd.service.ports.client }} + {{- end }} +{{- end }} + +{{/* + Check if etcd is explicitly enabled/disabled or implicitly enabled (for upgrades where enabled key was absent) + */}} +{{- define "etcdEnabled" -}} + {{- if eq (.Values.etcd.enabled) false }} + {{- "false" -}} + {{- else if eq (.Values.etcd.enabled) true }} + {{- "true" -}} + {{- else if .Values.etcd.externalUrl }} + {{- "false" -}} + {{- else }} + {{- "true" -}} + {{- end }} +{{- end }} + +{{/* +Renders init containers. If unset it sets the container image. +*/}} +{{- define "render_init_containers" -}} + {{- $containers := list }} + {{- $image := .context.Values.base.initContainers.image }} + {{- $values_image := .context.Values.image }} + {{- range .value -}} + {{ $container := . }} + {{- if not (hasKey . "imagePullPolicy") }} + {{- $pullPolicy := $image.pullPolicy | default $values_image.pullPolicy }} + {{- $_ := set $container "imagePullPolicy" $pullPolicy }} + {{- end }} + {{- if or (not $image) (not (hasKey . "image")) }} + {{- $registry := $image.registry | default $values_image.registry | default "docker.io" }} + {{- $namespace := $image.namespace | default $values_image.repo }} + {{- $name := $image.name | default "alpine-sh" }} + {{- $tag := $image.tag | default "4.1.0" }} + {{- $_ := set $container "image" (printf "%s/%s/%s:%s" $registry $namespace $name $tag) }} + {{- end }} + {{- $containers = append $containers $container }} + {{- end -}} + {{- tpl ($containers | toYaml) .context }} +{{- end -}} + +{{/* +Get the Events Jetstream Replica Count +*/}} +{{- define "events_replicas" -}} + {{- if .Values.nats.cluster.enabled }} + {{- min .Values.nats.cluster.replicas 3 }} + {{- else }} + {{- print "1" -}} + {{- end }} +{{- end -}} + +{{/* +Returns matched if the Etcd StatefulSet is of v8.6.0 +Usage: + {{- if include "etcd_is_8.6.0" . }} + Do something + {{- end }} +*/}} +{{- define "etcd_is_8.6.0" -}} + {{- $sts := lookup "apps/v1" "StatefulSet" .Release.Namespace (printf "%s-etcd" .Release.Name) -}} + {{/* + If no STS exists, erring on the side of caution and assuming there is one + and we made a mistake in finding it --> matched + */}} + {{- if not $sts -}} + matched + {{- else -}} + {{- if and $sts.metadata $sts.metadata.labels -}} + {{/* Grab value of chart label (or default to "") */}} + {{- $chart_name := index $sts.metadata.labels "helm.sh/chart" | default "" -}} + {{/* If it’s exactly "etcd-8.6.0" --> matched */}} + {{- if eq $chart_name "etcd-8.6.0" -}} + matched + {{- end -}} + {{- else -}} + {{/* + $sts exists, but doesn't have .metadata or .metadata.labels for some reason. + This may happen in a dry-run due to how lookup behaves. Erring on the side of caution and matching. + */}} + matched + {{- end -}} + {{- end -}} +{{- end }} diff --git a/charts/mayastor/templates/etcd/storage/localpv-storageclass.yaml b/charts/mayastor/templates/etcd/storage/localpv-storageclass.yaml new file mode 100644 index 0000000..f0cb431 --- /dev/null +++ b/charts/mayastor/templates/etcd/storage/localpv-storageclass.yaml @@ -0,0 +1,16 @@ +{{ if and (eq (include "etcdEnabled" .) "true") (and .Values.etcd.localpvScConfig.enabled .Values.etcd.persistence.enabled) }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" + - name: BasePath + value: {{ tpl (.Values.etcd.localpvScConfig.basePath | quote) . }} + openebs.io/cas-type: local + name: {{ (tpl (.Values.etcd.localpvScConfig.name) .) | required (print "StorageClass name for etcd localpv storage cannot be empty") }} +provisioner: openebs.io/local +reclaimPolicy: {{ .Values.etcd.localpvScConfig.reclaimPolicy }} +volumeBindingMode: {{ .Values.etcd.localpvScConfig.volumeBindingMode }} +{{ end }} diff --git a/charts/mayastor/templates/etcd/storage/localpv.yaml b/charts/mayastor/templates/etcd/storage/localpv.yaml new file mode 100644 index 0000000..d495d37 --- /dev/null +++ b/charts/mayastor/templates/etcd/storage/localpv.yaml @@ -0,0 +1,22 @@ +--- +{{ if and (eq (include "etcdEnabled" .) "true") (and .Values.etcd.persistence.enabled (eq .Values.etcd.persistence.storageClass "manual")) }} +{{- range $index, $end := until (.Values.etcd.replicaCount | int) }} +apiVersion: v1 +kind: PersistentVolume +metadata: + name: etcd-volume-{{ $index }} + labels: + statefulset.kubernetes.io/pod-name: {{ print $.Release.Name }}-etcd-{{ $index }} +spec: + storageClassName: manual + # You must also delete the hostpath on the node + persistentVolumeReclaimPolicy: {{ $.Values.etcd.persistentVolumeClaimRetentionPolicy.whenDeleted }} + capacity: + storage: {{ $.Values.etcd.persistence.size | quote }} + accessModes: + - ReadWriteOnce + hostPath: + path: "/var/local/{{ $.Release.Name }}/etcd/pod-{{ $index }}" +--- +{{- end }} +{{- end }} diff --git a/charts/mayastor/templates/jaeger-operator/jaeger.yaml b/charts/mayastor/templates/jaeger-operator/jaeger.yaml new file mode 100644 index 0000000..5face13 --- /dev/null +++ b/charts/mayastor/templates/jaeger-operator/jaeger.yaml @@ -0,0 +1,23 @@ +{{- if .Values.base.jaeger.enabled }} +apiVersion: jaegertracing.io/v1 +kind: Jaeger +metadata: + name: jaeger + namespace: {{ .Release.Namespace }} +labels: + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + strategy: allInOne + ingress: + enabled: false + {{- include "jaeger_scheduling" . }} + query: + serviceType: NodePort + nodePort: 30012 + storage: + type: memory + options: + memory: + max-traces: 100000 +{{- end }} diff --git a/charts/mayastor/templates/loki/storage/localpv-storageclass.yaml b/charts/mayastor/templates/loki/storage/localpv-storageclass.yaml new file mode 100644 index 0000000..857f6cc --- /dev/null +++ b/charts/mayastor/templates/loki/storage/localpv-storageclass.yaml @@ -0,0 +1,33 @@ +{{- if and (.Values.loki.localpvScConfig.enabled) (.Values.loki.singleBinary.persistence.enabled) (.Values.loki.enabled) }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" + - name: BasePath + value: {{ tpl ( .Values.loki.localpvScConfig.loki.basePath | quote ) . }} + openebs.io/cas-type: local + name: {{ tpl .Values.loki.localpvScConfig.loki.name . | required "StorageClass name for loki localpv storage cannot be empty" }} +provisioner: openebs.io/local +reclaimPolicy: {{ .Values.loki.localpvScConfig.loki.reclaimPolicy }} +volumeBindingMode: {{ .Values.loki.localpvScConfig.loki.volumeBindingMode }} +{{- end }} +--- +{{- if and (.Values.loki.localpvScConfig.enabled) (.Values.loki.minio.persistence.enabled) (.Values.loki.enabled) }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" + - name: BasePath + value: {{ tpl ( .Values.loki.localpvScConfig.minio.basePath | quote ) . }} + openebs.io/cas-type: local + name: {{ tpl .Values.loki.localpvScConfig.minio.name . | required "StorageClass name for loki localpv storage cannot be empty" }} +provisioner: openebs.io/local +reclaimPolicy: {{ .Values.loki.localpvScConfig.minio.reclaimPolicy }} +volumeBindingMode: {{ .Values.loki.localpvScConfig.minio.volumeBindingMode }} +{{- end }} diff --git a/charts/mayastor/templates/mayastor/agents/core/agent-core-deployment.yaml b/charts/mayastor/templates/mayastor/agents/core/agent-core-deployment.yaml new file mode 100644 index 0000000..78326b7 --- /dev/null +++ b/charts/mayastor/templates/mayastor/agents/core/agent-core-deployment.yaml @@ -0,0 +1,134 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-agent-core + labels: + app: agent-core + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + replicas: 1 + selector: + matchLabels: + app: agent-core + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + template: + metadata: + labels: + app: agent-core + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + serviceAccountName: {{ .Release.Name }}-service-account + imagePullSecrets: + {{- include "base_pull_secrets" . }} + initContainers: + {{- include "base_init_core_containers" . }} + {{- if $pcName := include "priority_class_with_default" (dict "template" . "localPriorityClass" .Values.agents.core.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if $tolerations := include "_tolerations_with_early_eviction" (dict "template" . "localTolerations" .Values.agents.core.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + containers: + - name: agent-core + resources: + limits: + cpu: {{ .Values.agents.core.resources.limits.cpu | quote }} + memory: {{ .Values.agents.core.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.agents.core.resources.requests.cpu | quote }} + memory: {{ .Values.agents.core.resources.requests.memory | quote }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ include "image_prefix" . }}-agent-core:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "--store={{ include "etcdUrl" . }}" + - "--request-timeout={{ default .Values.base.default_req_timeout .Values.agents.core.requestTimeout }}" + {{- if not .Values.agents.core.minTimeouts }} + - "--no-min-timeouts" + {{- end }} + - "--cache-period={{ .Values.base.cache_poll_period }}"{{ if .Values.base.jaeger.enabled }} + - "--jaeger={{ include "jaeger_url" . }}"{{ end }} + - "--grpc-server-addr=[::]:50051" + - "--pool-commitment={{ .Values.agents.core.capacity.thin.poolCommitment }}" + - "--snapshot-commitment={{ .Values.agents.core.capacity.thin.snapshotCommitment }}" + - "--volume-commitment-initial={{ .Values.agents.core.capacity.thin.volumeCommitmentInitial }}" + - "--volume-commitment={{ .Values.agents.core.capacity.thin.volumeCommitment }}"{{ if .Values.eventing.enabled }} + - "--events-url=nats://{{ .Release.Name }}-nats:4222" + - "--events-replicas={{ include "events_replicas" . }}"{{ end }}{{ if not .Values.agents.ha.enabled }} + - "--disable-ha"{{ end }} + - "--fmt-style={{ include "logFormat" . }}" + - "--ansi-colors={{ .Values.base.logging.color }}" + - "--create-volume-limit={{ .Values.agents.core.maxCreateVolume }}" + {{- if $wait := default ((.Values.agents.core.rebuild).partial).waitPeriod .Values.agents.core.partialRebuildWaitPeriod }} + - "--faulted-child-wait-period={{ $wait }}"{{ end }} + {{- if (.Values.agents.core.rebuild).maxConcurrent }} + - "--max-rebuilds={{ .Values.agents.core.rebuild.maxConcurrent }}"{{ end }} + {{- if eq ((.Values.agents.core.rebuild).partial).enabled false }} + - "--disable-partial-rebuild"{{ end }} + {{- if not (default false .Values.agents.core.volumeHealth) }} + - "--no-volume-health"{{ end }} + {{- if eq .Values.agents.core.encryptedPoolsSoftScheduling true }} + - "--encrypted-pools-soft-scheduling"{{- end }} + {{- if eq .Values.agents.core.allowNonPersistentDevlink true}} + - "--allow-non-persistent-devlink"{{- end }} + {{- with .Values.agents.core.poolClusterSize }} + - "--pool-cluster-size={{ . }}"{{- end }} + + ports: + - containerPort: 50051 + env: + - name: RUST_LOG + value: {{ .Values.agents.core.logLevel }} + {{- if default .Values.base.logging.silenceLevel .Values.agents.core.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logging.silenceLevel .Values.agents.core.logSilenceLevel }} + {{- end }} + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: agent-ha-cluster + resources: + limits: + cpu: {{ .Values.agents.ha.cluster.resources.limits.cpu | quote }} + memory: {{ .Values.agents.ha.cluster.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.agents.ha.cluster.resources.requests.cpu | quote }} + memory: {{ .Values.agents.ha.cluster.resources.requests.memory | quote }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ include "image_prefix" . }}-agent-ha-cluster:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "-g=[::]:50052" + - "--store=http://{{ include "etcdUrl" . }}" + - "--core-grpc=https://{{ .Release.Name }}-agent-core:50051"{{ if .Values.base.jaeger.enabled }} + - "--jaeger={{ include "jaeger_url" . }}"{{ end }}{{ if .Values.eventing.enabled }} + - "--events-url=nats://{{ .Release.Name }}-nats:4222" + - "--events-replicas={{ include "events_replicas" . }}"{{ end }} + - "--ansi-colors={{ .Values.base.logging.color }}" + - "--fmt-style={{ include "logFormat" . }}" + ports: + - containerPort: 50052 + env: + - name: RUST_LOG + value: {{ .Values.agents.core.logLevel }} + {{- if default .Values.base.logging.silenceLevel .Values.agents.core.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.logging.silenceLevel .Values.agents.core.logSilenceLevel }} + {{- end }} + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace diff --git a/charts/mayastor/templates/mayastor/agents/core/agent-core-service.yaml b/charts/mayastor/templates/mayastor/agents/core/agent-core-service.yaml new file mode 100644 index 0000000..52b39a4 --- /dev/null +++ b/charts/mayastor/templates/mayastor/agents/core/agent-core-service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-agent-core + labels: + app: agent-core + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + selector: + app: agent-core + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + ports: + - name: grpc + port: 50051 + - name: ha-cluster + port: 50052 diff --git a/charts/mayastor/templates/mayastor/agents/ha/ha-node-daemonset.yaml b/charts/mayastor/templates/mayastor/agents/ha/ha-node-daemonset.yaml new file mode 100644 index 0000000..44fc0e7 --- /dev/null +++ b/charts/mayastor/templates/mayastor/agents/ha/ha-node-daemonset.yaml @@ -0,0 +1,120 @@ +{{- if .Values.agents.ha.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ .Release.Name }}-agent-ha-node + labels: + app: agent-ha-node + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + selector: + matchLabels: + app: agent-ha-node + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + minReadySeconds: 10 + template: + metadata: + labels: + app: agent-ha-node + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + initContainers: + {{- include "base_init_ha_node_containers" . }} + imagePullSecrets: + {{- include "base_pull_secrets" . }} + {{- if $pcName := include "priority_class_with_default" (dict "template" . "localPriorityClass" .Values.agents.ha.node.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + nodeSelector: + {{- if .Values.nodeSelector }} + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.csi.node.topology.nodeSelector }} + {{- range $key, $val := .Values.csi.node.topology.segments }} + {{ $key }}: {{ $val }} + {{- end }} + {{- end }} + {{- if $tolerations := include "tolerations" (dict "template" . "localTolerations" .Values.agents.ha.node.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + containers: + - name: agent-ha-node + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ include "image_prefix" . }}-agent-ha-node:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + privileged: true + env: + - name: RUST_LOG + value: {{ .Values.agents.ha.node.logLevel }} + {{- if default .Values.base.logging.silenceLevel .Values.agents.ha.node.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logging.silenceLevel .Values.agents.ha.node.logSilenceLevel }} + {{- end }} + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: RUST_BACKTRACE + value: "1" + args: + - "--node-name=$(MY_NODE_NAME)" + - "--csi-socket={{ default .Values.csi.node.pluginMountPath .Values.csi.node.pluginMounthPath }}/{{ .Values.csi.node.socketPath }}" + - "--grpc-ip=$(MY_POD_IP)" + - "--grpc-port={{ default 50053 .Values.agents.ha.node.port }}" + - "--cluster-agent=https://{{ .Release.Name }}-agent-core:50052"{{ if .Values.base.jaeger.enabled }} + - "--jaeger={{ include "jaeger_url" . }}"{{ end }}{{ if .Values.eventing.enabled }} + - "--events-url=nats://{{ .Release.Name }}-nats:4222" + - "--events-replicas={{ include "events_replicas" . }}"{{ end }} + - "--ansi-colors={{ .Values.base.logging.color }}" + - "--fmt-style={{ include "logFormat" . }}" + volumeMounts: + - name: device + mountPath: /dev + - name: sys + mountPath: /sys + - name: run-udev + mountPath: /run/udev + - name: plugin-dir + mountPath: {{ default .Values.csi.node.pluginMountPath .Values.csi.node.pluginMounthPath }} + resources: + limits: + cpu: {{ .Values.agents.ha.node.resources.limits.cpu | quote }} + memory: {{ .Values.agents.ha.node.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.agents.ha.node.resources.requests.cpu | quote }} + memory: {{ .Values.agents.ha.node.resources.requests.memory | quote }} + ports: + - containerPort: {{ default 50053 .Values.agents.ha.node.port }} + protocol: TCP + name: ha-node + volumes: + - name: device + hostPath: + path: /dev + type: Directory + - name: sys + hostPath: + path: /sys + type: Directory + - name: run-udev + hostPath: + path: /run/udev + type: Directory + - name: plugin-dir + hostPath: + path: {{ .Values.csi.node.kubeletDir }}/plugins/io.openebs.mayastor/ + type: DirectoryOrCreate +{{- end }} diff --git a/charts/mayastor/templates/mayastor/apis/api-rest-deployment.yaml b/charts/mayastor/templates/mayastor/apis/api-rest-deployment.yaml new file mode 100644 index 0000000..e3d065c --- /dev/null +++ b/charts/mayastor/templates/mayastor/apis/api-rest-deployment.yaml @@ -0,0 +1,88 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-api-rest + labels: + app: api-rest + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + replicas: {{ .Values.apis.rest.replicaCount }} + selector: + matchLabels: + app: api-rest + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + template: + metadata: + labels: + app: api-rest + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + imagePullSecrets: + {{- include "base_pull_secrets" . }} + initContainers: + {{- include "base_init_containers" . }} + {{- if $pcName := include "priority_class_with_default" (dict "template" . "localPriorityClass" .Values.apis.rest.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if $tolerations := include "_tolerations_with_early_eviction" (dict "template" . "localTolerations" .Values.apis.rest.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + containers: + - name: api-rest + resources: + limits: + cpu: {{ .Values.apis.rest.resources.limits.cpu | quote }} + memory: {{ .Values.apis.rest.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.apis.rest.resources.requests.cpu | quote }} + memory: {{ .Values.apis.rest.resources.requests.memory | quote }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ include "image_prefix" . }}-api-rest:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "--dummy-certificates" + - "--no-auth" + - "--http=[::]:8081" + - "--request-timeout={{ .Values.base.default_req_timeout }}"{{ if .Values.base.jaeger.enabled }} + - "--jaeger={{ include "jaeger_url" . }}"{{ end }} + - "--core-grpc=https://{{ .Release.Name }}-agent-core:50051" + - "--ansi-colors={{ .Values.base.logging.color }}" + - "--fmt-style={{ include "logFormat" . }}" + {{- if .Values.apis.rest.healthProbes.readiness.enabled }} + - "--core-health-freq={{ .Values.apis.rest.healthProbes.readiness.agentCoreProbeFreq }}" + {{- end }} + ports: + - containerPort: 8080 + - containerPort: 8081 + env: + - name: RUST_LOG + value: {{ .Values.apis.rest.logLevel }} + {{- if default .Values.base.logging.silenceLevel .Values.apis.rest.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logging.silenceLevel .Values.apis.rest.logSilenceLevel }} + {{- end }} + {{- if .Values.apis.rest.healthProbes.readiness.enabled }} + readinessProbe: + httpGet: + path: /ready + port: 8081 + failureThreshold: {{ .Values.apis.rest.healthProbes.readiness.failureThreshold }} + initialDelaySeconds: {{ .Values.apis.rest.healthProbes.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.apis.rest.healthProbes.readiness.periodSeconds }} + timeoutSeconds: {{ .Values.apis.rest.healthProbes.readiness.timeoutSeconds }} + {{- end }} + {{- if .Values.apis.rest.healthProbes.liveness.enabled }} + livenessProbe: + httpGet: + path: /live + port: 8081 + failureThreshold: {{ .Values.apis.rest.healthProbes.liveness.failureThreshold }} + initialDelaySeconds: {{ .Values.apis.rest.healthProbes.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.apis.rest.healthProbes.liveness.periodSeconds }} + timeoutSeconds: {{ .Values.apis.rest.healthProbes.liveness.timeoutSeconds }} + {{- end }} diff --git a/charts/mayastor/templates/mayastor/apis/api-rest-service.yaml b/charts/mayastor/templates/mayastor/apis/api-rest-service.yaml new file mode 100644 index 0000000..37671f0 --- /dev/null +++ b/charts/mayastor/templates/mayastor/apis/api-rest-service.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-api-rest + labels: + app: api-rest + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + type: {{ .Values.apis.rest.service.type }} + selector: + app: api-rest + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + ports: + - port: 8080 + name: https + targetPort: 8080 + protocol: TCP + {{- if eq .Values.apis.rest.service.type "NodePort" }} + nodePort: {{ .Values.apis.rest.service.nodePorts.https }} + {{- end }} + - port: 8081 + name: http + targetPort: 8081 + protocol: TCP + {{- if eq .Values.apis.rest.service.type "NodePort" }} + nodePort: {{ .Values.apis.rest.service.nodePorts.http }} + {{- end }} diff --git a/charts/mayastor/templates/mayastor/csi/csi-controller-deployment.yaml b/charts/mayastor/templates/mayastor/csi/csi-controller-deployment.yaml new file mode 100644 index 0000000..4efbb22 --- /dev/null +++ b/charts/mayastor/templates/mayastor/csi/csi-controller-deployment.yaml @@ -0,0 +1,142 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-csi-controller + labels: + app: csi-controller + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + replicas: 1 + selector: + matchLabels: + app: csi-controller + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + template: + metadata: + labels: + app: csi-controller + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + hostNetwork: true + serviceAccountName: {{ .Release.Name }}-service-account + dnsPolicy: ClusterFirstWithHostNet + imagePullSecrets: + {{- include "base_pull_secrets" . }} + initContainers: + {{- include "jaeger_collector_init_container" . }} + {{- include "rest_agent_init_container" . }} + {{- if $pcName := include "priority_class_with_default" (dict "template" . "localPriorityClass" .Values.csi.controller.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if $tolerations := include "_tolerations_with_early_eviction" (dict "template" . "localTolerations" .Values.csi.controller.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + containers: + - name: csi-controller + resources: + limits: + cpu: {{ .Values.csi.controller.resources.limits.cpu | quote }} + memory: {{ .Values.csi.controller.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.csi.controller.resources.requests.cpu | quote }} + memory: {{ .Values.csi.controller.resources.requests.memory | quote }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ include "image_prefix" . }}-csi-controller:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "--csi-socket=/var/lib/csi/sockets/pluginproxy/csi.sock" + - "--rest-endpoint=http://{{ .Release.Name }}-api-rest:8081"{{ if .Values.base.jaeger.enabled }} + - "--jaeger={{ include "jaeger_url" . }}"{{ end }} + {{- range $key, $val := .Values.csi.node.topology.segments }} + - "--node-selector={{ $key }}={{ $val }}" + {{- end }} + - "--ansi-colors={{ .Values.base.logging.color }}" + - "--fmt-style={{ include "logFormat" . }}" + - "--create-volume-limit={{ .Values.csi.controller.maxCreateVolume }}" + - "--enable-orphan-vol-gc={{- .Values.csi.controller.enableDangerousRetainGC | default false }}" + env: + - name: RUST_LOG + value: {{ .Values.csi.controller.logLevel }} + {{- if default .Values.base.logging.silenceLevel .Values.csi.controller.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logging.silenceLevel .Values.csi.controller.logSilenceLevel }} + {{- end }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-provisioner + image: "{{ .Values.csi.image.registry }}/{{ .Values.csi.image.repo }}/csi-provisioner:{{ .Values.csi.image.provisionerTag }}" + args: + - "--v=2" + - "--csi-address=$(ADDRESS)" + - "--feature-gates=Topology=true" + - "--strict-topology=false" + - "--default-fstype=ext4" + - "--extra-create-metadata" # This is needed for volume group feature to work + - "--timeout=36s" + - "--worker-threads={{ .Values.csi.controller.maxCreateVolume }}" # 10 for create and 10 for delete + {{- if default .Values.csi.controller.preventVolumeModeConversion }} + - "--prevent-volume-mode-conversion" + {{- end }} + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-attacher + image: "{{ .Values.csi.image.registry }}/{{ .Values.csi.image.repo }}/csi-attacher:{{ .Values.csi.image.attacherTag }}" + args: + - "--v=2" + - "--timeout=36s" + - "--csi-address=$(ADDRESS)" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-snapshotter + image: "{{ .Values.csi.image.registry }}/{{ .Values.csi.image.repo }}/csi-snapshotter:{{ .Values.csi.image.snapshotterTag }}" + args: + - "--v=2" + - "--csi-address=$(ADDRESS)" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-snapshot-controller + args: + - "--v=2" + - "--leader-election=false" # since we are running single container + {{- if default .Values.csi.controller.preventVolumeModeConversion }} + - "--prevent-volume-mode-conversion" + {{- end }} + image: "{{ .Values.csi.image.registry }}/{{ .Values.csi.image.repo }}/snapshot-controller:{{ .Values.csi.image.snapshotControllerTag }}" + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + - name: csi-resizer + args: + - "--v=2" + - "--csi-address=$(ADDRESS)" + - "--handle-volume-inuse-error=false" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + image: "{{ .Values.csi.image.registry }}/{{ .Values.csi.image.repo }}/csi-resizer:{{ .Values.csi.image.resizerTag }}" + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + volumes: + - name: socket-dir + emptyDir: diff --git a/charts/mayastor/templates/mayastor/csi/csi-node-daemonset.yaml b/charts/mayastor/templates/mayastor/csi/csi-node-daemonset.yaml new file mode 100644 index 0000000..406163f --- /dev/null +++ b/charts/mayastor/templates/mayastor/csi/csi-node-daemonset.yaml @@ -0,0 +1,176 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ .Release.Name }}-csi-node + labels: + app: csi-node + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{- range $key, $val := .Values.csi.node.topology.segments }} + {{ $key }}: {{ $val }} + {{- end }} +spec: + selector: + matchLabels: + app: csi-node + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + minReadySeconds: 10 + template: + metadata: + labels: + app: csi-node + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + serviceAccountName: {{ .Release.Name }}-service-account + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + imagePullSecrets: + {{- include "base_pull_secrets" . }} + {{- if $pcName := include "priority_class_with_default" (dict "template" . "localPriorityClass" .Values.csi.node.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + nodeSelector: + {{- if .Values.nodeSelector }} + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.csi.node.topology.nodeSelector }} + {{- range $key, $val := .Values.csi.node.topology.segments }} + {{ $key }}: {{ $val }} + {{- end }} + {{- end }} + {{- if $tolerations := include "tolerations" (dict "template" . "localTolerations" .Values.csi.node.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + initContainers: + {{- include "csi_node_init_containers" . }} + # NOTE: Each container must have mem/cpu limits defined in order to + # belong to Guaranteed QoS class, hence can never get evicted in case of + # pressure unless they exceed those limits. limits and requests must be + # the same. + containers: + - name: csi-node + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ include "image_prefix" . }}-csi-node:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + # we need privileged because we mount filesystems and use mknod + securityContext: + privileged: true + env: + - name: RUST_LOG + value: {{ .Values.csi.node.logLevel }} + {{- if default .Values.base.logging.silenceLevel .Values.csi.node.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logging.silenceLevel .Values.csi.node.logSilenceLevel }} + {{- end }} + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: RUST_BACKTRACE + value: "1" + {{- if (.Values.csi.node.mkfs_args).xfs }} + - name: MKFS_XFS_ARGS + value: {{ .Values.csi.node.mkfs_args.xfs | quote }} + {{- end }} + {{- if $safeMount := .Values.base.safeMount }} + - name: USE_SAFE_MOUNT + value: {{ $safeMount | quote }} + {{- end }} + args: + - "--csi-socket={{ default .Values.csi.node.pluginMountPath .Values.csi.node.pluginMounthPath }}/{{ .Values.csi.node.socketPath }}" + - "--node-name=$(MY_NODE_NAME)" + - "--rest-endpoint=http://{{ .Release.Name }}-api-rest:8081"{{ if .Values.csi.node.restClient.enabled }} + - "--enable-rest"{{ end }} + - "--enable-registration" + - "--grpc-ip=$(MY_POD_IP)" + - "--grpc-port={{ default 10199 .Values.csi.node.port }}"{{ if .Values.csi.node.nvme.io_timeout }} + - "--nvme-io-timeout={{ .Values.csi.node.nvme.io_timeout }}" + - "--nvme-core-io-timeout={{ .Values.csi.node.nvme.io_timeout }}"{{ else }} + - "--nvme-io-timeout={{ .Values.io_engine.nvme.ioTimeout }}10s" + - "--nvme-core-io-timeout={{ .Values.io_engine.nvme.ioTimeout }}10s"{{ end }}{{ if .Values.csi.node.nvme.ctrl_loss_tmo }} + - "--nvme-ctrl-loss-tmo={{ .Values.csi.node.nvme.ctrl_loss_tmo }}"{{ end }}{{ if .Values.csi.node.nvme.keep_alive_tmo }} + - "--nvme-keep-alive-tmo={{ .Values.csi.node.nvme.keep_alive_tmo }}"{{ end }} + - "--nvme-nr-io-queues={{ include "coreCount" . }}" + - "--nvme-connect-fallback={{ .Values.csi.node.nvme.tcpFallback }}" + - "--kubelet-path={{ .Values.csi.node.kubeletDir }}" + {{- range $key, $val := .Values.csi.node.topology.segments }} + - "--node-selector={{ $key }}={{ $val }}" + {{- end }} + - "--fmt-style={{ include "logFormat" . }}" + - "--ansi-colors={{ .Values.base.logging.color }}" + volumeMounts: + - name: device + mountPath: /dev + - name: sys + mountPath: /sys + - name: run-udev + mountPath: /run/udev + - name: plugin-dir + mountPath: {{ default .Values.csi.node.pluginMountPath .Values.csi.node.pluginMounthPath }} + - name: kubelet-dir + mountPath: {{ .Values.csi.node.kubeletDir }} + mountPropagation: "Bidirectional" + resources: + limits: + cpu: {{ .Values.csi.node.resources.limits.cpu | quote }} + memory: {{ .Values.csi.node.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.csi.node.resources.requests.cpu | quote }} + memory: {{ .Values.csi.node.resources.requests.memory | quote }} + - name: csi-driver-registrar + image: "{{ .Values.csi.image.registry }}/{{ .Values.csi.image.repo }}/csi-node-driver-registrar:{{ .Values.csi.image.registrarTag }}" + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + args: + - "--csi-address={{ default .Values.csi.node.pluginMountPath .Values.csi.node.pluginMounthPath }}/{{ .Values.csi.node.socketPath }}" + - "--kubelet-registration-path={{ .Values.csi.node.kubeletDir }}/plugins/io.openebs.mayastor/csi.sock" + volumeMounts: + - name: plugin-dir + mountPath: {{ default .Values.csi.node.pluginMountPath .Values.csi.node.pluginMounthPath }} + - name: registration-dir + mountPath: /registration + resources: + limits: + cpu: "100m" + memory: "50Mi" + requests: + cpu: "100m" + memory: "50Mi" + # Mayastor node plugin gRPC server + ports: + - containerPort: {{ default 10199 .Values.csi.node.port }} + protocol: TCP + name: mayastor-node + volumes: + - name: device + hostPath: + path: /dev + type: Directory + - name: sys + hostPath: + path: /sys + type: Directory + - name: run-udev + hostPath: + path: /run/udev + type: Directory + - name: registration-dir + hostPath: + path: {{ .Values.csi.node.kubeletDir }}/plugins_registry/ + type: Directory + - name: plugin-dir + hostPath: + path: {{ .Values.csi.node.kubeletDir }}/plugins/io.openebs.mayastor/ + type: DirectoryOrCreate + - name: kubelet-dir + hostPath: + path: {{ .Values.csi.node.kubeletDir }} + type: Directory diff --git a/charts/mayastor/templates/mayastor/io/io-engine-daemonset.yaml b/charts/mayastor/templates/mayastor/io/io-engine-daemonset.yaml new file mode 100644 index 0000000..58404b2 --- /dev/null +++ b/charts/mayastor/templates/mayastor/io/io-engine-daemonset.yaml @@ -0,0 +1,179 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ .Release.Name }}-io-engine + labels: + app: io-engine + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + selector: + matchLabels: + app: io-engine + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + updateStrategy: + type: OnDelete + minReadySeconds: 10 + template: + metadata: + labels: + app: io-engine + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + serviceAccountName: {{ .Release.Name }}-service-account + imagePullSecrets: + {{- include "base_pull_secrets" . }} + hostNetwork: true + # To resolve services in the namespace + dnsPolicy: ClusterFirstWithHostNet + nodeSelector: {{- .Values.io_engine.nodeSelector | toYaml | nindent 8 }} + {{- if $pcName := include "priority_class_with_default" (dict "template" . "localPriorityClass" .Values.io_engine.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + {{- if .Values.runtimeClassName }} + runtimeClassName: {{ .Values.runtimeClassName | quote }} + {{- end }} + {{- if $tolerations := include "tolerations" (dict "template" . "localTolerations" .Values.io_engine.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + initContainers: + {{- include "base_init_containers" . }} + containers: + - name: io-engine + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ include "image_prefix" . }}-io-engine:{{ default .Values.image.tag .Values.image.repoTags.dataPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: RUST_LOG + value: {{ .Values.io_engine.logLevel }} + - name: NVMF_TCP_MAX_QPAIRS_PER_CTRL + value: "{{ .Values.io_engine.nvme.tcp.maxQpairsPerCtrl }}" + - name: NVMF_TCP_MAX_QUEUE_DEPTH + value: "{{ .Values.io_engine.nvme.tcp.maxQueueDepth }}" + - name: NVME_TIMEOUT + value: "{{ .Values.io_engine.nvme.ioTimeout }}" + - name: NVME_TIMEOUT_ADMIN + value: "{{ .Values.io_engine.nvme.adminTimeout }}" + - name: NVME_KATO + value: "{{ .Values.io_engine.nvme.keepAliveTimeout }}" + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: NEXUS_NVMF_ANA_ENABLE + value: "1" + - name: NEXUS_NVMF_RESV_ENABLE + value: "1" + {{- if $safeMount := .Values.base.safeMount }} + - name: USE_SAFE_MOUNT + value: {{ $safeMount | quote }} + {{- end }} + args: + # The -l argument accepts cpu-list. Indexing starts at zero. + # For example -l 1,2,10-20 means use core 1, 2, 10 to 20. + # Note: Ensure that the CPU resources are updated accordingly. + # If you use 2 CPUs, the CPU: field should also read 2. + - "--grpc-ip=$(MY_POD_IP)" + - "--grpc-port={{ default 10124 .Values.io_engine.port }}" + - "-N$(MY_NODE_NAME)" + - "-Rhttps://{{ .Release.Name }}-agent-core:50051" + - "-y/var/local/{{ .Release.Name }}/io-engine/config.yaml" + - "-l{{ include "cpuFlag" . }}" + - "-p={{ include "etcdUrl" . }}"{{ if .Values.io_engine.target.nvmf.ptpl }} + - "--ptpl-dir=/var/local/{{ .Release.Name }}/io-engine/ptpl/"{{ end }} + - "--api-versions={{ .Values.io_engine.api }}"{{ if .Values.io_engine.target.nvmf.rdma.enabled }} + - "--enable-rdma"{{ end }}{{ if .Values.io_engine.target.nvmf.iface }} + - "-T={{ .Values.io_engine.target.nvmf.iface }}"{{ end }}{{ if .Values.io_engine.envcontext }} + - "--env-context=--{{ .Values.io_engine.envcontext }}"{{ end }}{{ if .Values.io_engine.reactorFreezeDetection.enabled }} + - "--reactor-freeze-detection"{{ end }} + - "--tgt-crdt={{ .Values.io_engine.target.nvmf.hostCmdRetryDelay.crdt1 }}"{{ if .Values.eventing.enabled }} + - "--events-url=nats://{{ .Release.Name }}-nats:4222" + - "--events-replicas={{ include "events_replicas" . }}"{{ end }} + - "--ps-retries={{ default 300 .Values.io_engine.pstorRetries }}" + command: + - io-engine + securityContext: + privileged: true + volumeMounts: + - name: device + mountPath: /dev + - name: udev + mountPath: /run/udev + - name: dshm + mountPath: /dev/shm + - name: configlocation + mountPath: /var/local/{{ .Release.Name }}/io-engine/ + - name: hugepages-2mi + mountPath: /dev/hugepages-2mi + {{- if .Values.io_engine.resources.requests.hugepages1Gi }} + - name: hugepages-1gi + mountPath: /dev/hugepages-1gi + {{- end }} + resources: + limits: + cpu: {{ .Values.io_engine.resources.limits.cpu | default (include "coreCount" .) | quote }} + memory: {{ .Values.io_engine.resources.limits.memory | quote }} + hugepages-2Mi: {{ .Values.io_engine.resources.limits.hugepages2Mi | quote }} + hugepages-1Gi: {{ .Values.io_engine.resources.requests.hugepages1Gi | quote }} + requests: + cpu: {{ .Values.io_engine.resources.requests.cpu | default (include "coreCount" .) | quote }} + memory: {{ .Values.io_engine.resources.requests.memory | quote }} + hugepages-2Mi: {{ .Values.io_engine.resources.requests.hugepages2Mi | quote }} + hugepages-1Gi: {{ .Values.io_engine.resources.requests.hugepages1Gi | quote }} + ports: + - containerPort: {{ default 10124 .Values.io_engine.port }} + protocol: TCP + name: io-engine + {{- if .Values.base.metrics.enabled }} + - name: metrics-exporter-io-engine + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ include "image_prefix" . }}-metrics-exporter-io-engine:{{ default .Values.image.tag .Values.image.repoTags.extensions }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + ports: + - containerPort: {{ default 9502 .Values.base.metrics.port }} + protocol: TCP + name: metrics + args: + - "--metrics-endpoint=[::]:{{ default 9502 .Values.base.metrics.port }}" + - "--grpc-port={{ default 10124 .Values.io_engine.port }}" + - "--fmt-style={{ include "logFormat" . }}" + - "--ansi-colors={{ .Values.base.logging.color }}" + {{- end }} + volumes: + - name: device + hostPath: + path: /dev + type: Directory + - name: udev + hostPath: + path: /run/udev + type: Directory + - name: dshm + emptyDir: + medium: Memory + sizeLimit: "1Gi" + - name: hugepages-2mi + emptyDir: + medium: HugePages-2Mi + {{- if .Values.io_engine.resources.requests.hugepages1Gi }} + - name: hugepages-1gi + emptyDir: + medium: HugePages-1Gi + {{- end }} + - name: configlocation + hostPath: + path: /var/local/{{ .Release.Name }}/io-engine/ + type: DirectoryOrCreate diff --git a/charts/mayastor/templates/mayastor/metrics/metrics-exporter-io-engine-service.yaml b/charts/mayastor/templates/mayastor/metrics/metrics-exporter-io-engine-service.yaml new file mode 100644 index 0000000..286a708 --- /dev/null +++ b/charts/mayastor/templates/mayastor/metrics/metrics-exporter-io-engine-service.yaml @@ -0,0 +1,19 @@ +{{- if .Values.base.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-metrics-exporter-io-engine + labels: + app: metrics-exporter-io-engine + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + ports: + - name: metrics + port: 9502 + targetPort: 9502 + protocol: TCP + selector: + app: io-engine + {{ include "label_prefix" . }}/release: {{ .Release.Name }} +{{- end }} diff --git a/charts/mayastor/templates/mayastor/obs/obs-callhome-deployment.yaml b/charts/mayastor/templates/mayastor/obs/obs-callhome-deployment.yaml new file mode 100644 index 0000000..7c9cf10 --- /dev/null +++ b/charts/mayastor/templates/mayastor/obs/obs-callhome-deployment.yaml @@ -0,0 +1,87 @@ +{{- if .Values.obs.callhome.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-obs-callhome + labels: + app: obs-callhome + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + replicas: 1 + selector: + matchLabels: + app: obs-callhome + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + template: + metadata: + labels: + app: obs-callhome + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + serviceAccountName: {{ .Release.Name }}-service-account + imagePullSecrets: + {{- include "base_pull_secrets" . }} + {{- if $pcName := include "priority_class" (dict "template" . "localPriorityClass" .Values.obs.callhome.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if $tolerations := include "tolerations" (dict "template" . "localTolerations" .Values.obs.callhome.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + containers: + - name: obs-callhome + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ include "image_prefix" . }}-obs-callhome:{{ default .Values.image.tag .Values.image.repoTags.extensions }}" + args: + - "-e http://{{ .Release.Name }}-api-rest:8081" + - "-n {{ .Release.Namespace }}"{{ if .Values.eventing.enabled }} + - "--aggregator-url=http://{{ .Release.Name }}-obs-callhome-stats:9090/stats"{{ end }} + {{ if .Values.obs.callhome.sendReport }} + - "--send-report" + {{ end }} + env: + - name: RUST_LOG + value: {{ .Values.obs.callhome.logLevel }} + {{- if .Values.obs.callhome.productName }} + - name: CALLHOME_PRODUCT_NAME + value: {{ .Values.obs.callhome.productName | quote }} + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + limits: + cpu: {{ .Values.obs.callhome.resources.limits.cpu | quote }} + memory: {{ .Values.obs.callhome.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.obs.callhome.resources.requests.cpu | quote }} + memory: {{ .Values.obs.callhome.resources.requests.memory | quote }} + {{- if .Values.eventing.enabled }} + - name: obs-callhome-stats + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ include "image_prefix" . }}-obs-callhome-stats:{{ default .Values.image.tag .Values.image.repoTags.extensions }}" + args: + - "--namespace={{ .Release.Namespace }}" + - "--release-name={{ .Release.Name }}" + - "--events-url=nats://{{ .Release.Name }}-nats:4222" + - "--events-replicas={{ include "events_replicas" . }}" + - "--ansi-colors={{ .Values.base.logging.color }}" + - "--fmt-style={{ include "logFormat" . }}" + ports: + - containerPort: 9090 + protocol: TCP + name: stats + env: + - name: RUST_LOG + value: {{ .Values.obs.stats.logLevel }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + limits: + cpu: {{ .Values.obs.stats.resources.limits.cpu | quote }} + memory: {{ .Values.obs.stats.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.obs.stats.resources.requests.cpu | quote }} + memory: {{ .Values.obs.stats.resources.requests.memory | quote }} + {{- end }} +{{- end }} diff --git a/charts/mayastor/templates/mayastor/obs/stats-service.yaml b/charts/mayastor/templates/mayastor/obs/stats-service.yaml new file mode 100644 index 0000000..8a85a1e --- /dev/null +++ b/charts/mayastor/templates/mayastor/obs/stats-service.yaml @@ -0,0 +1,29 @@ +{{- if .Values.obs.callhome.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-obs-callhome-stats + labels: + app: obs-callhome + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + ports: + - port: 9090 + name: https + targetPort: 9090 + protocol: TCP + {{- if eq .Values.obs.stats.service.type "NodePort" }} + nodePort: {{ .Values.obs.stats.service.nodePorts.https }} + {{- end }} + - port: 9091 + name: http + targetPort: 9091 + protocol: TCP + {{- if eq .Values.obs.stats.service.type "NodePort" }} + nodePort: {{ .Values.obs.stats.service.nodePorts.http }} + {{- end }} + selector: + app: obs-callhome + {{ include "label_prefix" . }}/release: {{ .Release.Name }} +{{- end }} diff --git a/charts/mayastor/templates/mayastor/operators/operator-diskpool-deployment.yaml b/charts/mayastor/templates/mayastor/operators/operator-diskpool-deployment.yaml new file mode 100644 index 0000000..ee73f8f --- /dev/null +++ b/charts/mayastor/templates/mayastor/operators/operator-diskpool-deployment.yaml @@ -0,0 +1,66 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-operator-diskpool + labels: + app: operator-diskpool + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + replicas: 1 + selector: + matchLabels: + app: operator-diskpool + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + template: + metadata: + labels: + app: operator-diskpool + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + serviceAccountName: {{ .Release.Name }}-service-account + imagePullSecrets: + {{- include "base_pull_secrets" . }} + initContainers: + {{- include "base_init_containers" . }} + {{- if $pcName := include "priority_class_with_default" (dict "template" . "localPriorityClass" .Values.operators.pool.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if $tolerations := include "_tolerations_with_early_eviction" (dict "template" . "localTolerations" .Values.operators.pool.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + containers: + - name: operator-diskpool + resources: + limits: + cpu: {{ .Values.operators.pool.resources.limits.cpu | quote }} + memory: {{ .Values.operators.pool.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.operators.pool.resources.requests.cpu | quote }} + memory: {{ .Values.operators.pool.resources.requests.memory | quote }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ include "image_prefix" . }}-operator-diskpool:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "-e http://{{ .Release.Name }}-api-rest:8081" + - "-n{{ .Release.Namespace }}" + - "--request-timeout={{ .Values.base.default_req_timeout }}" + - "--interval={{ .Values.base.cache_poll_period }}"{{ if .Values.base.jaeger.enabled }} + - "--jaeger={{ include "jaeger_url" . }}"{{ end }} + - "--ansi-colors={{ .Values.base.logging.color }}" + - "--fmt-style={{ include "logFormat" . }}" + env: + - name: RUST_LOG + value: {{ .Values.operators.pool.logLevel }} + {{- if default .Values.base.logging.silenceLevel .Values.operators.pool.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logging.silenceLevel .Values.operators.pool.logSilenceLevel }} + {{- end }} + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name diff --git a/charts/mayastor/templates/mayastor/priority-class/priority-class.yaml b/charts/mayastor/templates/mayastor/priority-class/priority-class.yaml new file mode 100644 index 0000000..22f3909 --- /dev/null +++ b/charts/mayastor/templates/mayastor/priority-class/priority-class.yaml @@ -0,0 +1,7 @@ +apiVersion: scheduling.k8s.io/v1 +description: Used for critical pods that must run in the cluster, which can be moved to another node if necessary. +kind: PriorityClass +metadata: + name: {{ .Release.Name }}-cluster-critical +preemptionPolicy: PreemptLowerPriority +value: 1000000000 diff --git a/charts/mayastor/templates/mayastor/rbac/rbac.yaml b/charts/mayastor/templates/mayastor/rbac/rbac.yaml new file mode 100644 index 0000000..0bb52b6 --- /dev/null +++ b/charts/mayastor/templates/mayastor/rbac/rbac.yaml @@ -0,0 +1,131 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-service-account + namespace: {{ .Release.Namespace }} + labels: + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-cluster-role + labels: + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +rules: + # must create mayastor crd if it doesn't exist, replace if exist, + # merge schema to existing CRD. +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "get", "update", "list", "patch", "replace"] + # must update stored_version in status to include new schema only. +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions/status"] + verbs: ["get", "update", "patch"] + # must read mayastorpools info. This is needed to handle upgrades from v1. +- apiGroups: [ "openebs.io" ] + resources: [ "mayastorpools" ] + verbs: ["get", "list", "patch", "delete", "deletecollection"] + # must read diskpool info +- apiGroups: ["openebs.io"] + resources: ["diskpools"] + verbs: ["get", "list", "watch", "update", "replace", "patch", "create"] + # must update diskpool status +- apiGroups: ["openebs.io"] + resources: ["diskpools/status"] + verbs: ["update", "patch"] + # must read cm info +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["create", "get", "update", "patch"] + # must get deployments info +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "list"] + # external provisioner & attacher +- apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update", "create", "delete", "patch"] +- apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch", "patch"] + + # external provisioner +- apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update", "patch"] +- apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] +- apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + + # external-resizer +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] +- apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["patch"] + + # external snapshotter and snapshot-controller +- apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] +- apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create","get", "list", "watch", "update", "patch", "delete"] +- apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] +- apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update", "patch", "delete"] +- apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update", "patch"] + +- apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + + # external attacher +- apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "update", "patch"] +- apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] + # CSI nodes must be listed +- apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + # get kube-system namespace to retrieve Uid +- apiGroups: [""] + resources: ["namespaces"] + verbs: ["get"] + + # get secrets for encryption +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-cluster-role-binding + labels: + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +subjects: +- kind: ServiceAccount + name: {{ .Release.Name }}-service-account + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Release.Name }}-cluster-role + apiGroup: rbac.authorization.k8s.io diff --git a/charts/mayastor/templates/pre-upgrade-hook.yaml b/charts/mayastor/templates/pre-upgrade-hook.yaml new file mode 100644 index 0000000..b43f1a8 --- /dev/null +++ b/charts/mayastor/templates/pre-upgrade-hook.yaml @@ -0,0 +1,142 @@ +{{- if .Values.preUpgradeHook.enabled }} +{{- if .Release.IsUpgrade }} +{{- if include "etcd_is_8.6.0" . }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: mayastor-pre-upgrade-hook + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-weight": "-9999" + {{- with .Values.preUpgradeHook.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: mayastor-pre-upgrade-hook + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-weight": "-9999" + {{- with .Values.preUpgradeHook.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["list", "patch"] + - apiGroups: ["apps"] + resources: ["statefulsets"] + verbs: ["get", "create", "delete", "list", "watch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: mayastor-pre-upgrade-hook + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-weight": "-9998" + {{- with .Values.preUpgradeHook.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +subjects: + - kind: ServiceAccount + name: mayastor-pre-upgrade-hook + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: mayastor-pre-upgrade-hook + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: "mayastor-pre-upgrade-hook" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-weight": "-9999" + {{- with .Values.preUpgradeHook.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +data: + label-etcd-for-helm-release.sh: |- + {{- .Files.Get "label-etcd-for-helm-release.sh" | nindent 4 }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: "mayastor-pre-upgrade-hook" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-weight": "-9997" + {{- with .Values.preUpgradeHook.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + template: + metadata: + name: "mayastor-pre-upgrade-hook" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + {{- with .Values.preUpgradeHook.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: "mayastor-pre-upgrade-hook" + {{- with .Values.preUpgradeHook.tolerations }} + tolerations: + {{- toYaml . | nindent 6 }} + {{- end }} + restartPolicy: Never + volumes: + - name: scripts + configMap: + name: "mayastor-pre-upgrade-hook" + defaultMode: 0777 + containers: + - name: mayastor-pre-upgrade-hook + image: {{ .Values.preUpgradeHook.image.registry }}/{{ .Values.preUpgradeHook.image.repo }}:{{ .Values.preUpgradeHook.image.tag }} + imagePullPolicy: {{ .Values.preUpgradeHook.image.pullPolicy }} + command: + - "sh" + - "-c" + args: + - "/scripts/label-etcd-for-helm-release.sh {{ .Release.Name }} -n {{ .Release.Namespace }}" + volumeMounts: + - name: scripts + mountPath: /scripts + {{- if .Values.preUpgradeHook.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.preUpgradeHook.imagePullSecrets | nindent 8 }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/mayastor/templates/storageclass.yaml b/charts/mayastor/templates/storageclass.yaml new file mode 100644 index 0000000..2c04db1 --- /dev/null +++ b/charts/mayastor/templates/storageclass.yaml @@ -0,0 +1,22 @@ +{{ if .Values.storageClass.enabled }} +{{- $scName := (printf "%s-%s" .Release.Name .Values.storageClass.nameSuffix | trunc 63) }} +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: {{ $scName }} + {{- if .Values.storageClass.default }} + annotations: + storageclass.kubernetes.io/is-default-class: "true" + {{- end }} +allowVolumeExpansion: {{ .Values.storageClass.allowVolumeExpansion }} +parameters: +{{/* + Set StorageClass parameters by adding to the values.yaml 'storageClass.parameters' map. + Don't add the parameters to this template directly. + This is done so that during an upgrade, an existing default StorageClass's config can + be given preference over this chart's defaults. +*/}} +{{ $valuesParams := .Values.storageClass.parameters }} +{{ (include "storageClass.parameters" (list $scName $valuesParams)) | indent 2 }} +provisioner: io.openebs.csi-mayastor +{{ end }} \ No newline at end of file diff --git a/charts/mayastor/values.yaml b/charts/mayastor/values.yaml new file mode 100644 index 0000000..886e9b0 --- /dev/null +++ b/charts/mayastor/values.yaml @@ -0,0 +1,992 @@ +crds: + # -- Disables the installation of all CRDs if set to false + enabled: true + csi: + volumeSnapshots: + # -- Install Volume Snapshot CRDs + enabled: true + +global: + security: + allowInsecureImages: true + +image: + # -- Image registry to pull our product images + registry: docker.io + # -- Image registry's namespace + repo: openebs + # -- Release tag for our images + tag: v2.10.0 + repoTags: + # Note: Below image tag configuration is optional and typically should never be + # used. Setting specific image tags for the different repositories proves useful + # for some integration testing scenarios. Use the 'tag' option above to set + # release/pre-release container image tags. + # The below tag values will be picked for images by default. + # If not specified, 'tag' option provided above will be picked. + controlPlane: "" + dataPlane: "" + extensions: "" + # -- ImagePullPolicy for our images + pullPolicy: IfNotPresent + # -- docker-secrets required to pull images if the container registry from image.registry is protected + pullSecrets: [] +# -- Node labels for pod assignment +# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +# Note that if multi-arch images support 'kubernetes.io/arch: amd64' +# should be removed and set 'nodeSelector' to empty '{}' as default value. +nodeSelector: + kubernetes.io/arch: amd64 +# -- Pod scheduling priority. +# Setting this value will apply to all components except the external Chart dependencies. +# If any component has `priorityClassName` set, then this value would be overridden for that component. +# For external components like etcd, jaeger or loki, PriorityClass can only be set at component level. +priorityClassName: "" +earlyEvictionTolerations: + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 5 + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 5 +# -- Tolerations to be applied to all components except external Chart dependencies. +# If any component has tolerations set, then it would override this value. +# For external components like etcd, jaeger and loki, tolerations can only be set at component level. +tolerations: [] +base: + # -- Request timeout for rest & core agents + default_req_timeout: 5s + # -- Cache timeout for core agent & diskpool deployment + cache_poll_period: 30s + logging: + # -- Valid values for format are pretty, json and compact + format: pretty + # -- Enable ansi color code for Pod StdOut/StdErr + color: true + # -- Silence specific module components + silenceLevel: + initContainers: + enabled: true + image: + name: alpine-sh + tag: 4.3.0 + pullPolicy: IfNotPresent + containers: + - name: agent-core-grpc-probe + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 {{ .Release.Name }}-agent-core 50051; do date; echo "Waiting for agent-core-grpc services..."; sleep 1; done;'] + - name: etcd-probe + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 {{ include "etcdUrl" . }} {{ .Values.etcd.service.ports.client }}; do date; echo "Waiting for etcd..."; sleep 1; done;'] + initHaNodeContainers: + enabled: true + containers: + - name: agent-cluster-grpc-probe + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 {{ .Release.Name }}-agent-core 50052; do date; echo "Waiting for agent-cluster-grpc services..."; sleep 1; done;'] + initCoreContainers: + enabled: true + containers: + - name: etcd-probe + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 {{ include "etcdUrl" . }} {{ .Values.etcd.service.ports.client }}; do date; echo "Waiting for etcd..."; sleep 1; done;'] + metrics: + # -- Enable the metrics exporter + enabled: true + # -- Container port for the metrics exporter service + port: 9502 + jaeger: + # Enable jaeger tracing (for development only). + # Since version 1.31 the Jaeger Operator uses webhooks to validate Jaeger custom resources (CRs). + # This requires an installed version of the cert-manager. + enabled: false + initContainer: true + agent: + name: jaeger-agent + port: 6831 + initContainer: + - name: jaeger-probe + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 -u {{.Values.base.jaeger.agent.name}} {{.Values.base.jaeger.agent.port}}; do date; echo "Waiting for jaeger..."; sleep 1; done;'] + collector: + name: jaeger-collector + port: 4317 + initContainer: + - name: jaeger-probe + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 -u {{.Values.base.jaeger.collector.name}} {{.Values.base.jaeger.collector.port}}; do date; echo "Waiting for jaeger..."; sleep 1; done;'] + initRestContainer: + enabled: true + initContainer: + - name: api-rest-probe + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 {{ .Release.Name }}-api-rest 8081; do date; echo "Waiting for REST API endpoint to become available"; sleep 1; done;'] +operators: + pool: + # -- Log level for diskpool operator service + logLevel: info + resources: + limits: + # -- Cpu limits for diskpool operator + cpu: "100m" + # -- Memory limits for diskpool operator + memory: "32Mi" + requests: + # -- Cpu requests for diskpool operator + cpu: "50m" + # -- Memory requests for diskpool operator + memory: "16Mi" + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global + priorityClassName: "" +jaeger-operator: + # Name of jaeger operator + name: "{{ .Release.Name }}" + jaeger: + # Install jaeger-operator + create: false + collector: + service: + otlp: + grpc: true + rbac: + # Create a clusterRole for Jaeger + clusterRole: true + tolerations: [] + priorityClassName: "" +agents: + core: + # -- Request timeout for core agents + # Default value is defined in .base.default_req_timeout + requestTimeout: + # -- Enable minimal timeouts + minTimeouts: true + # -- Log level for the core service + logLevel: info + capacity: + thin: + # -- The allowed pool commitment limit when dealing with thin provisioned volumes. + # Example: If the commitment is 250 and the pool is 10GiB we can overcommit the pool + # up to 25GiB (create 2 10GiB and 1 5GiB volume) but no further. + poolCommitment: "250%" + # -- When creating replicas for an existing volume, each replica pool must have at least + # this much free space percentage of the volume size. + # Example: if this value is 40, the pool has 40GiB free, then the max volume size allowed + # to be created on the pool is 100GiB. + volumeCommitment: "40%" + # -- Same as the `volumeCommitment` argument, but applicable only when creating replicas + # for a new volume. + volumeCommitmentInitial: "40%" + # -- When creating snapshots for an existing volume, each replica pool must have at least + # this much free space percentage of the volume size. + # Example: if this value is 40, the pool has 40GiB free, then the max volume size allowed + # to be snapped on the pool is 100GiB. + snapshotCommitment: "40%" + rebuild: + # -- The maximum number of system-wide rebuilds permitted at any given time. + # If set to an empty string, there are no limits. + maxConcurrent: "" + partial: + # -- Partial rebuild uses a log of missed IO to rebuild replicas which have become temporarily faulted, + # hence a bit faster, depending on the log size. + enabled: true + # -- If a faulted replica comes back online within this time period then it will be + # rebuilt using the partial rebuild capability. Otherwise, the replica will be fully rebuilt. + # A blank value "" means internally derived value will be used. + waitPeriod: "" + # The maximum number of concurrent create volume requests. + maxCreateVolume: 10 + # -- Enable extended volume health information, which helps generate the volume status more accurately. + volumeHealth: true + resources: + limits: + # -- Cpu limits for core agents + cpu: "1000m" + # -- Memory limits for core agents + memory: "128Mi" + requests: + # -- Cpu requests for core agents + cpu: "500m" + # -- Memory requests for core agents + memory: "32Mi" + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global. + # If both local and global are not set, the final deployment manifest has a mayastor custom critical priority class assigned to the pod by default. + # Refer the `templates/_helpers.tpl` and `templates/mayastor/agents/core/agent-core-deployment.yaml` for more details. + priorityClassName: "" + # -- Prefer encrypted pools for volume replicas. + # If a volume wasn't provisioned with a encryption storageclass, we try to place the replicas of such volume on best-effort basis onto encrypted pools, if this global is set. + # This is effective subject to volume spec already modified via plugin to request encryption. + encryptedPoolsSoftScheduling: false + # -- Allow using non-persistent kernel devpaths for pool disks. + # Enabling this will let users to use the kernel devpaths e.g /dev/sda, for diskpools. However, this comes with associated risks if the devpaths + # get swapped among disks, resulting in total data loss especially if encryption is being used. + allowNonPersistentDevlink: false + # -- Default blobstore cluster size for diskpools, in bytes. + # This value is used as a default value of blobstore cluster size on diskpools. This is set to 4MiB internally by default, if nothing specified here. + # The value is also configurable via Diskpool CR, which takes precedence over this setting. This is an advanced configuration, please refer documentation to + # understand the usage and implications of this. + poolClusterSize: "" + ha: + enabled: true + node: + # -- Log level for the ha node service + logLevel: info + resources: + limits: + # -- Cpu limits for ha node agent + cpu: "100m" + # -- Memory limits for ha node agent + memory: "64Mi" + requests: + # -- Cpu requests for ha node agent + cpu: "100m" + # -- Memory requests for ha node agent + memory: "64Mi" + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global + priorityClassName: "" + # -- Container port for the ha-node service + port: 50053 + cluster: + # -- Log level for the ha cluster service + logLevel: info + resources: + limits: + # -- Cpu limits for ha cluster agent + cpu: "100m" + # -- Memory limits for ha cluster agent + memory: "64Mi" + requests: + # -- Cpu requests for ha cluster agent + cpu: "100m" + # -- Memory requests for ha cluster agent + memory: "16Mi" +apis: + rest: + # -- Log level for the rest service + logLevel: info + healthProbes: + readiness: + # -- Toggle readiness probe. + enabled: true + # -- Frequency for the agent-core liveness probe. + agentCoreProbeFreq: "20s" + # -- No. of failures the readiness probe will tolerate. + failureThreshold: 2 + # -- No. of seconds of delay before checking the readiness status. + initialDelaySeconds: 0 + # -- No. of seconds between readiness probe checks. + periodSeconds: 20 + # -- No. of seconds of timeout tolerance. + timeoutSeconds: 5 + liveness: + # -- Toggle liveness probe. + enabled: true + # -- No. of failures the liveness probe will tolerate. + failureThreshold: 1 + # -- No. of seconds of delay before checking the liveness status. + initialDelaySeconds: 0 + # -- No. of seconds between liveness probe checks. + periodSeconds: 30 + # -- No. of seconds of timeout tolerance. + timeoutSeconds: 5 + # -- Number of replicas of rest + replicaCount: 1 + resources: + limits: + # -- Cpu limits for rest + cpu: "100m" + # -- Memory limits for rest + memory: "64Mi" + requests: + # -- Cpu requests for rest + cpu: "50m" + # -- Memory requests for rest + memory: "32Mi" + # Rest service parameters define how the rest service is exposed + service: + # -- Rest K8s service type + type: ClusterIP + # Ports from where rest endpoints are accessible from outside the cluster, only valid if type is NodePort + nodePorts: + # NodePort associated with http port + http: 30011 + # NodePort associated with https port + https: 30010 + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global. + # If both local and global are not set, the final deployment manifest has a mayastor custom critical priority class assigned to the pod by default. + # Refer the `templates/_helpers.tpl` and `templates/mayastor/apis/rest/api-rest-deployment.yaml` for more details. + priorityClassName: "" +csi: + image: + # -- Image registry to pull all CSI Sidecar images + registry: registry.k8s.io + # -- Image registry's namespace + repo: sig-storage + # -- imagePullPolicy for all CSI Sidecar images + pullPolicy: IfNotPresent + # -- csi-provisioner image release tag + provisionerTag: v5.2.0 + # -- csi-attacher image release tag + attacherTag: v4.8.1 + # -- csi-snapshotter image release tag + snapshotterTag: v8.2.0 + # -- csi-snapshot-controller image release tag + snapshotControllerTag: v8.2.0 + # -- csi-node-driver-registrar image release tag + registrarTag: v2.13.0 + # -- csi-resizer image release tag + resizerTag: v1.13.2 + controller: + # -- Log level for the csi controller + logLevel: info + # The maximum number of concurrent create volume requests. + maxCreateVolume: 10 + resources: + limits: + # -- Cpu limits for csi controller + cpu: "32m" + # -- Memory limits for csi controller + memory: "128Mi" + requests: + # -- Cpu requests for csi controller + cpu: "16m" + # -- Memory requests for csi controller + memory: "64Mi" + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global + priorityClassName: "" + # -- Prevent modifying the volume mode when creating a PVC from an existing VolumeSnapshot + preventVolumeModeConversion: true + # Enable auto garbage collection of volume resources which were associated with `Retain` PV's. + # Before enabling this, make sure you're well aware of the dangerous downsides. + # For more information see: . + enableDangerousRetainGC: false + node: + logLevel: info + topology: + segments: + openebs.io/csi-node: mayastor + # -- Add topology segments to the csi-node and agent-ha-node daemonset node selector + nodeSelector: false + resources: + limits: + # -- Cpu limits for csi node plugin + cpu: "100m" + # -- Memory limits for csi node plugin + memory: "128Mi" + requests: + # -- Cpu requests for csi node plugin + cpu: "100m" + # -- Memory requests for csi node plugin + memory: "64Mi" + nvme: + # The nvme_core module and nvme block io timeout in humantime + # By default it uses the "io_engine.nvme.ioTimeout" + 10s + # Do not modify this unless you're really sure about its effects + io_timeout: "" + # -- The ctrl_loss_tmo (controller loss timeout) in seconds + ctrl_loss_tmo: "1980" + # Kato (keep alive timeout) in seconds + keep_alive_tmo: "" + # -- Fallback to nvme-tcp if nvme-rdma is enabled for Mayastor but rdma is not available on a particular csi-node + tcpFallback: true + # -- The kubeletDir directory for the csi-node plugin + kubeletDir: /var/lib/kubelet + pluginMountPath: /csi + socketPath: csi.sock + # Additional arguments when creating filesystems + mkfs_args: + xfs: "" + restClient: + enabled: true + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global + priorityClassName: "" + initContainers: + enabled: false + containers: + - name: nvme-tcp-probe + command: ['sh', '-c', 'trap "exit 1" TERM; until [ -d /sys/module/nvme_tcp ]; do [ -z "$WARNED" ] && echo "nvme_tcp module not loaded..."; WARNED=1; sleep 60; done;'] + # -- Container port for the csi-node service + port: 10199 +io_engine: + # -- Log level for the io-engine service + logLevel: info + api: "v1" + target: + nvmf: + # -- Enable RDMA + # Capability of Mayastor nvmf target to take RDMA connections if the cluster nodes have RDMA device(s) + # configured from RNIC. + rdma: + enabled: false + # -- NVMF target interface (ip, mac, name or subnet) + # If RDMA is enabled, please set iface to an RDMA + # capable netdev name from host network. Example, if an rdma device mlx5_0 is + # available on a netdev eth0 on RNIC, as can be seen from `rdma link` command output, + # then this field should be set to eth0. + iface: "" + # -- Reservations Persist Through Power Loss State + ptpl: true + # NVMF target Command Retry Delay for volume target initiators + hostCmdRetryDelay: + # A command retry delay in milliseconds. A value of 0 means no delay, host may retry immediately + crdt1: 30 + nvme: + # -- Timeout for IOs + # The default here is exaggerated for local disks, but we've observed that in + # shared virtual environments having a higher timeout value is beneficial. + # Please adjust this according to your hardware and needs. + ioTimeout: "110s" + # Timeout for admin commands + adminTimeout: "30s" + # Timeout for keep alives + keepAliveTimeout: "10s" + tcp: + # -- Max size setting (both initiator and target) for an NVMe queue + # -- You may need to increase this for a higher outstanding IOs per volume + maxQueueDepth: "32" + # Max qpairs per controller. + maxQpairsPerCtrl: "32" + # -- Pass additional arguments to the Environment Abstraction Layer. + # Example: --set {product}.envcontext=iova-mode=pa + envcontext: "" + reactorFreezeDetection: + enabled: false + # -- The number of cores that each io-engine instance will bind to. + cpuCount: "2" + # -- If not empty, overrides the cpuCount and explicitly sets the list of cores. + # Example: --set='io_engine.coreList={30,31}' + coreList: [] + # -- Node selectors to designate storage nodes for diskpool creation + # Note that if multi-arch images support 'kubernetes.io/arch: amd64' + # should be removed. + nodeSelector: + openebs.io/engine: mayastor + kubernetes.io/arch: amd64 + resources: + limits: + # -- Cpu limits for the io-engine + cpu: "" + # -- Memory limits for the io-engine + memory: "1Gi" + # -- Hugepage memory in 2MiB chunks + hugepages2Mi: "2Gi" + # -- Hugepage memory in 1GiB chunks + hugepages1Gi: + requests: + # -- Cpu requests for the io-engine + cpu: "" + # -- Memory requests for the io-engine + memory: "1Gi" + # -- Hugepage memory in 2MiB chunks + hugepages2Mi: "2Gi" + # -- Hugepage memory in 1GiB chunks + hugepages1Gi: + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global + priorityClassName: "" + # -- Runtime class to use. Defaults to cluster standard + runtimeClassName: "" + # -- Number of retries for pstor persistence before the volume target self shutdowns + pstorRetries: 300 + # -- Container port for the io-engine service + port: 10124 +etcd: + # -- Disable when using an external etcd cluster. + enabled: true + # -- (string) Url of the external etcd cluster. Note, etcd.enable must be set to false. + externalUrl: "" + # Configuration for etcd's localpv hostpath storage class. + localpvScConfig: + enabled: true + # Name of etcd's localpv hostpath storage class. + name: "mayastor-etcd-localpv" + # -- Host path where local etcd data is stored in. + basePath: "/var/local/{{ .Release.Name }}/localpv-hostpath/etcd" + # -- ReclaimPolicy of etcd's localpv hostpath storage class. + reclaimPolicy: Delete + # -- VolumeBindingMode of etcd's localpv hostpath storage class. + volumeBindingMode: WaitForFirstConsumer + # Pod labels; okay to remove the openebs logging label if required + podLabels: + app: etcd + openebs.io/logging: "true" + # -- Number of replicas of etcd + replicaCount: 3 + # -- Kubernetes Cluster Domain + clusterDomain: cluster.local + # TLS authentication for client-to-server communications + # ref: https://etcd.io/docs/current/op-guide/security/ + auth: + client: + secureTransport: false + # TLS authentication for server-to-server communications + # ref: https://etcd.io/docs/current/op-guide/security/ + peer: + secureTransport: false + rbac: + create: false + allowNoneAuthentication: true + # Enable persistence using Persistent Volume Claims + persistence: + # -- If true, use a Persistent Volume Claim. If false, use emptyDir. + enabled: true + # -- Will define which storageClass to use in etcd's StatefulSets. Options: + #

- `"manual"` - Will provision a hostpath PV on the same node.
+ # - `""` (empty) - Will use the default StorageClass on the cluster.

+ storageClass: "mayastor-etcd-localpv" + # -- Volume size + size: 2Gi + persistentVolumeClaimRetentionPolicy: + # -- PVC's reclaimPolicy + enabled: false + whenDeleted: Retain + whenScaled: Retain + # -- Use a PreStop hook to remove the etcd members from the etcd cluster on container termination + # Ignored if lifecycleHooks is set or replicaCount=1 + removeMemberOnContainerTermination: false + # -- AutoCompaction + # Since etcd keeps an exact history of its keyspace, this history should be + # periodically compacted to avoid performance degradation + # and eventual storage space exhaustion. + # Auto compaction mode. Valid values: "periodic", "revision". + # - 'periodic' for duration based retention, defaulting to hours if no time unit is provided (e.g. 5m). + # - 'revision' for revision number based retention. + autoCompactionMode: revision + # -- Auto compaction retention length. 0 means disable auto compaction. + autoCompactionRetention: "100" + extraEnvVars: + # -- Raise alarms when backend size exceeds the given quota. + - name: ETCD_QUOTA_BACKEND_BYTES + value: "8589934592" + # Init containers parameters: + # volumePermissions: Change the owner and group of the persistent volume mountpoint to runAsUser:fsGroup values from the securityContext section. + # + volumePermissions: + # chown the mounted volume; this is required if a statically provisioned hostpath volume is used + enabled: true + image: + registry: docker.io + repository: openebs/alpine-bash + tag: 4.3.0 + pullSecrets: [] + image: + registry: docker.io + repository: openebs/etcd + # extra debug information on logs + debug: false + # -- Pod anti-affinity preset + # Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + podAntiAffinityPreset: "hard" + ## -- nodeSelector [object] Node labels for pod assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + nodeSelector: {} + # etcd service parameters defines how the etcd service is exposed + service: + # K8s service type + type: ClusterIP + ports: + # etcd client port + client: 2379 + # Specify the nodePort(s) value(s) for the LoadBalancer and NodePort service types. + # ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + # + nodePorts: + # Port from where etcd endpoints are accessible from outside cluster + client: 31379 + peer: "" + tolerations: [] + priorityClassName: "" + preUpgradeJob: + annotations: + "helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation" +loki: + enabled: true + # NOTE: For all possible storage options for loki, check https://github.com/openebs/mayastor-extensions/blob/HEAD/chart/loki-storage.md + # Configuration for loki's localpv hostpath storage class. + localpvScConfig: + enabled: true + loki: + # Name of loki's localpv hostpath storage class. + name: "mayastor-loki-localpv" + # -- Host path where local loki data is stored in. + basePath: "/var/local/{{ .Release.Name }}/localpv-hostpath/loki" + # -- ReclaimPolicy of loki's localpv hostpath storage class. + reclaimPolicy: Delete + # -- VolumeBindingMode of loki's localpv hostpath storage class. + volumeBindingMode: WaitForFirstConsumer + minio: + # Name of minio's localpv hostpath storage class. + name: "mayastor-minio-localpv" + # -- Host path where local minio data is stored in. + basePath: "/var/local/{{ .Release.Name }}/localpv-hostpath/minio" + # -- ReclaimPolicy of minio's localpv hostpath storage class. + reclaimPolicy: Delete + # -- VolumeBindingMode of minio's localpv hostpath storage class. + volumeBindingMode: WaitForFirstConsumer + loki: + serviceLabels: + app: loki + podLabels: + app: loki + schemaConfig: + configs: + - from: 2024-04-01 + store: tsdb + object_store: s3 + schema: v13 + index: + prefix: loki_index_ + period: 24h + commonConfig: + replication_factor: 3 + ingester: + chunk_encoding: snappy + # Configure these if a quicker ingestion is needed, i.e. faster push to your bucket. + # chunk_idle_period: 3m + # chunk_retain_period: 1m + # max_chunk_age: 6m + tracing: + enabled: true + querier: + max_concurrent: 1 + limits_config: + ingestion_burst_size_mb: 1000 + ingestion_rate_mb: 10000 + singleBinary: + replicas: 3 + drivesPerNode: 1 + persistence: + enabled: true + storageClass: "mayastor-loki-localpv" + accessModes: + - ReadWriteOnce + size: 2Gi + minio: + replicas: 3 + drivesPerNode: 1 + mode: distributed + # Disable this if you want to enabled external s3 bucket, and uncomment the storage section above. + enabled: true + persistence: + storageClass: "mayastor-loki-localpv" + size: 2Gi + deploymentMode: SingleBinary + lokiCanary: + enabled: false + chunksCache: + enabled: false + test: + enabled: false + gateway: + enabled: false + resultsCache: + enabled: false + backend: + replicas: 0 + read: + replicas: 0 + write: + replicas: 0 + ingester: + replicas: 0 + querier: + replicas: 0 + queryFrontend: + replicas: 0 + queryScheduler: + replicas: 0 + distributor: + replicas: 0 + compactor: + replicas: 0 + indexGateway: + replicas: 0 + bloomCompactor: + replicas: 0 + bloomGateway: + replicas: 0 + sidecar: + image: + repository: docker.io/kiwigrid/k8s-sidecar +alloy: + logging_config: + # Enable debugging on alloy components. + debugging: false + # -- Labels to enable scraping on, at-least one of these labels should be present. + labels: + openebs.io/logging: true + # -- X-Scope-OrgID to pe populated which pushing logs. Make sure the caller also uses the same. + tenant_id: openebs + enabled: true + alloy: + mounts: + varlog: true + configMap: + create: true + content: | + livedebugging { + enabled = {{ .Values.logging_config.debugging }} + } + + discovery.kubernetes "{{ .Release.Name }}_pods_name" { + role = "pod" + } + + discovery.relabel "{{ .Release.Name }}_pods_name" { + targets = discovery.kubernetes.{{ .Release.Name }}_pods_name.targets + + {{- $labels := .Values.logging_config.labels }} + {{- if $labels }} + {{- $keys := (keys $labels | sortAlpha) }} + + rule { + source_labels = [ + {{- range $key := $keys }} + "__meta_kubernetes_pod_label_{{ $key | replace "." "_" | replace "/" "_" }}", + {{- end }} + ] + separator = ";" + regex = "^{{ include "regex_or" (dict "labels" $labels "keys" $keys) }}$" + action = "keep" + } + + {{- end }} + + rule { + regex = "__meta_kubernetes_pod_label_(.+)" + action = "labelmap" + } + + rule { + regex = "__meta_kubernetes_pod_label_(.+)" + action = "labelmap" + } + + rule { + source_labels = ["__meta_kubernetes_namespace"] + separator = "/" + target_label = "job" + } + + rule { + source_labels = ["__meta_kubernetes_pod_name"] + target_label = "pod" + } + + rule { + source_labels = ["__meta_kubernetes_pod_container_name"] + target_label = "container" + } + + rule { + source_labels = ["__meta_kubernetes_pod_node_name"] + target_label = "hostname" + } + + rule { + source_labels = ["__meta_kubernetes_pod_uid", "__meta_kubernetes_pod_container_name"] + separator = "/" + target_label = "__path__" + replacement = "/var/log/pods/*$1/*.log" + } + } + + local.file_match "{{ .Release.Name }}_pod_files" { + path_targets = discovery.relabel.{{ .Release.Name }}_pods_name.output + } + + loki.source.file "{{ .Release.Name }}_pod_logs" { + targets = local.file_match.{{ .Release.Name }}_pod_files.targets + forward_to = [loki.process.{{ .Release.Name }}_process_logs.receiver] + } + + loki.process "{{ .Release.Name }}_process_logs" { + forward_to = [loki.write.default.receiver] + + stage.docker { } + + stage.replace { + expression = "(\\n)" + replace = "" + } + + stage.multiline { + firstline = "^ \\x1b\\[2m(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2}).(\\d{6})Z" + } + + stage.multiline { + firstline = "^ (\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2}).(\\d{6})Z" + } + } + + loki.write "default" { + endpoint { + url = "http://{{ .Release.Name }}-loki:3100/loki/api/v1/push" + tenant_id = "{{ .Values.logging_config.tenant_id }}" + } + external_labels = {} + } + + {{- define "regex_or" -}} + {{- $labels := .labels -}} + {{- $keys := .keys -}} + {{- $numKeys := len $keys -}} + {{- $regexParts := list -}} + {{- range $i, $key := $keys -}} + {{- $part := list -}} + {{- range $j := until $numKeys -}} + {{- if eq $j $i -}} + {{- $part = append $part (get $labels $key) -}} + {{- else -}} + {{- $part = append $part ".*" -}} + {{- end -}} + {{- end -}} + {{- $regexParts = append $regexParts (join ";" $part) -}} + {{- end -}} + {{- join "|" $regexParts -}} + {{- end -}} +# Eventing which enables or disables eventing-related components. +eventing: + enabled: true +# Configuration for the nats message-bus. This is an eventing component, and is enabled when +# 'eventing.enabled' is set to 'true'. +nats: + nats: + image: + pullPolicy: IfNotPresent + registry: docker.io + jetstream: + enabled: true + memStorage: + enabled: true + # Size of nats message is around 0.3 KB, so it can store around 10K messages. + size: "5Mi" + fileStorage: + enabled: false + # Affinity for pod assignment + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: nats + topologyKey: kubernetes.io/hostname + cluster: + enabled: true + replicas: 3 + # Define if NATS is using FQDN name for clustering (i.e. nats-0.nats.default.svc.cluster.local) or short name (i.e. nats-0.nats.default). + useFQDN: false + statefulSetPodLabels: + app: nats + openebs.io/logging: "true" + # The nats box can be installed for debugging, by default its enabled. + natsbox: + enabled: false + image: + registry: docker.io + reloader: + image: + registry: docker.io + exporter: + image: + registry: docker.io +obs: + callhome: + # -- Enable callhome + enabled: true + # -- Log level for callhome + logLevel: "info" + sendReport: true + resources: + limits: + # -- Cpu limits for callhome + cpu: "100m" + # -- Memory limits for callhome + memory: "32Mi" + requests: + # -- Cpu requests for callhome + cpu: "50m" + # -- Memory requests for callhome + memory: "16Mi" + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global + priorityClassName: "" + # Eventing component enabled/disabled based on obs.callhome.enabled value + stats: + # -- Log level for stats + logLevel: "info" + resources: + limits: + # -- Cpu limits for stats + cpu: "100m" + # -- Memory limits for stats + memory: "32Mi" + requests: + # -- Cpu requests for stats + cpu: "50m" + # -- Memory requests for stats + memory: "16Mi" + service: + # -- Rest K8s service type + type: ClusterIP + # Ports from where rest endpoints are accessible from outside the cluster, only valid if type is NodePort + nodePorts: + # NodePort associated with http port + http: 90011 + # NodePort associated with https port + https: 90010 +storageClass: + enabled: true + nameSuffix: single-replica + default: false + # -- Enable volume expansion for the default StorageClass. + allowVolumeExpansion: true + parameters: + protocol: nvmf + repl: 1 +localpv-provisioner: + # -- Enables the openebs dynamic-localpv-provisioner. If disabled, modify etcd and loki storage class accordingly. + enabled: true + localpv: + # -- Set the PriorityClass for the LocalPV Hostpath provisioner Deployment. + priorityClassName: "{{ .Release.Name }}-cluster-critical" + hostpathClass: + # -- Enable default hostpath localpv StorageClass. + enabled: false + analytics: + enabled: true +preUpgradeHook: + # -- Enable/Disable mayastor pre-upgrade hook + enabled: true + # -- Node tolerations for server scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # -- Optional array of imagePullSecrets containing private registry credentials + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + imagePullSecrets: [] + # - name: secretName + # Labels to be added to the Job Pod. + podLabels: + openebs.io/logging: "true" + # Extra annotations to be added to all the hook resources. + # This helps in debugging by leaving the Job/Pod instances lying around + annotations: + "helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation" + image: + # -- The container image registry URL for the hook job + registry: docker.io + # -- The container repository for the hook job + repo: openebs/kubectl + # -- The container image tag for the hook job + tag: "1.25.15" + # -- The imagePullPolicy for the container + pullPolicy: IfNotPresent diff --git a/charts/openebs-crds/.helmignore b/charts/openebs-crds/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/openebs-crds/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/openebs-crds/Chart.yaml b/charts/openebs-crds/Chart.yaml new file mode 100644 index 0000000..07121fc --- /dev/null +++ b/charts/openebs-crds/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +description: A Helm chart that collects CustomResourceDefinitions (CRDs) from OpenEBS. +name: openebs-crds +version: 4.4.0 diff --git a/charts/openebs-crds/helm.md b/charts/openebs-crds/helm.md new file mode 100644 index 0000000..9376168 --- /dev/null +++ b/charts/openebs-crds/helm.md @@ -0,0 +1,12 @@ +# openebs-crds + +![Version: 4.4.0](https://img.shields.io/badge/Version-4.4.0-informational?style=flat-square) + +A Helm chart that collects CustomResourceDefinitions (CRDs) from OpenEBS. + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| csi.volumeSnapshots.enabled | bool | `true` | Install Volume Snapshot CRDs | +| csi.volumeSnapshots.keep | bool | `true` | Keep CRDs on chart uninstall | diff --git a/charts/openebs-crds/templates/_helpers.tpl b/charts/openebs-crds/templates/_helpers.tpl new file mode 100644 index 0000000..8e6eef8 --- /dev/null +++ b/charts/openebs-crds/templates/_helpers.tpl @@ -0,0 +1,18 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* + Adds extra annotations to CRDs. This targets two scenarios: preventing CRD recycling in case + the chart is removed; and adding custom annotations. + NOTE: This function assumes the element `metadata.annotations` already exists. + Usage: + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} +*/}} + +{{- define "crds.extraAnnotations" -}} +{{- if .keep -}} +helm.sh/resource-policy: keep +{{ end }} +{{- with .annotations }} + {{- toYaml . }} +{{- end }} +{{- end -}} \ No newline at end of file diff --git a/charts/openebs-crds/templates/csi-volume-snapshot-class.yaml b/charts/openebs-crds/templates/csi-volume-snapshot-class.yaml new file mode 100644 index 0000000..ba00aa3 --- /dev/null +++ b/charts/openebs-crds/templates/csi-volume-snapshot-class.yaml @@ -0,0 +1,155 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: | + Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshotClass + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: false + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/openebs-crds/templates/csi-volume-snapshot-content.yaml b/charts/openebs-crds/templates/csi-volume-snapshot-content.yaml new file mode 100644 index 0000000..96c4a98 --- /dev/null +++ b/charts/openebs-crds/templates/csi-volume-snapshot-content.yaml @@ -0,0 +1,499 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + oneOf: + - required: + - snapshotHandle + - required: + - volumeHandle + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + sourceVolumeMode: + description: SourceVolumeMode is the mode of the volume whose snapshot + is taken. Can be either “Filesystem” or “Block”. If not specified, + it indicates the source volume's mode is unknown. This field is + immutable. This field is an alpha field. + type: string + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: | + If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future. + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: | + Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: | + creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + volumeGroupSnapshotContentName: + description: VolumeGroupSnapshotContentName is the name of the VolumeGroupSnapshotContent + of which this VolumeSnapshotContent is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshotContent + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: | + If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future. + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: | + Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/openebs-crds/templates/csi-volume-snapshot.yaml b/charts/openebs-crds/templates/csi-volume-snapshot.yaml new file mode 100644 index 0000000..024eb0d --- /dev/null +++ b/charts/openebs-crds/templates/csi-volume-snapshot.yaml @@ -0,0 +1,400 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + oneOf: + - required: + - persistentVolumeClaimName + - required: + - volumeSnapshotContentName + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + volumeSnapshotClassName: + description: | + VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field. + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: | + boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + x-kubernetes-int-or-string: true + volumeGroupSnapshotName: + description: VolumeGroupSnapshotName is the name of the VolumeGroupSnapshot + of which this VolumeSnapshot is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshot + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: | + spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required. + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + volumeSnapshotClassName: + description: | + VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field. + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: | + boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/openebs-crds/values.yaml b/charts/openebs-crds/values.yaml new file mode 100644 index 0000000..adfe8d4 --- /dev/null +++ b/charts/openebs-crds/values.yaml @@ -0,0 +1,6 @@ +csi: + volumeSnapshots: + # -- Install Volume Snapshot CRDs + enabled: true + # -- Keep CRDs on chart uninstall + keep: true diff --git a/charts/rawfile-localpv/.helmignore b/charts/rawfile-localpv/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/rawfile-localpv/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/rawfile-localpv/Chart.lock b/charts/rawfile-localpv/Chart.lock new file mode 100644 index 0000000..756ee4d --- /dev/null +++ b/charts/rawfile-localpv/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: crds + repository: "" + version: 0.0.1 +digest: sha256:eada35ade10b2e420bcff49387a38c1d75d4841081f7630e5e1f5dd5fe6390c5 +generated: "2025-11-20T16:39:08.138493849Z" diff --git a/charts/rawfile-localpv/Chart.yaml b/charts/rawfile-localpv/Chart.yaml new file mode 100644 index 0000000..1eacb4b --- /dev/null +++ b/charts/rawfile-localpv/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +appVersion: 0.12.0 +dependencies: +- condition: crds.enabled + name: crds + repository: "" + version: 0.0.1 +description: RawFile Driver Container Storage Interface +home: https://openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/main/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- filesystem +- sparse +- rawfile +- Local Persistent Volumes +- storage +kubeVersion: '>= 1.21' +name: rawfile-localpv +sources: +- https://github.com/openebs/rawfile-localpv +type: application +version: 0.12.0 diff --git a/charts/rawfile-localpv/README.md b/charts/rawfile-localpv/README.md new file mode 100644 index 0000000..72e6ca1 --- /dev/null +++ b/charts/rawfile-localpv/README.md @@ -0,0 +1,102 @@ +# rawfile-localpv + +![Version: 0.12.0](https://img.shields.io/badge/Version-0.12.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.12.0](https://img.shields.io/badge/AppVersion-0.12.0-informational?style=flat-square) + +RawFile Driver Container Storage Interface + +**Homepage:** + +## Source Code + +* + +## Requirements + +Kubernetes: `>= 1.21` + +| Repository | Name | Version | +|------------|------|---------| +| | crds | 0.0.1 | + +## Install and Upgrades + +Please follow the [install guide](https://github.com/openebs/rawfile-localpv/tree/v0.12.0/docs/install-guide.md) + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| auth.enabled | bool | `true` | Enables authentication for internal gRPC server | +| auth.token | string | `""` | Sets authentication token for internal gRPC server, will generate one if nothing provided | +| capacityOverride | string | `""` | Overrides total capacity of the storage for data dir storage on each host (Support size values) [e.g. `50GB` or `10MiB`] | +| controller.externalResizer.image.registry | string | `""` | Image registry for `csi-resizer` | +| controller.externalResizer.image.repository | string | `"sig-storage/csi-resizer"` | Image Repository for `csi-resizer` | +| controller.externalResizer.image.tag | string | `"v1.13.2"` | Image tag for `csi-resizer` | +| controller.grpcWorkers | int | `10` | Number of gRPC workers for controller component | +| controller.image.pullPolicy | string | `""` | Overrides default image pull policy for node component | +| controller.image.repository | string | `""` | Overrides default image repository for node component | +| controller.image.tag | string | `""` | Overrides default image tag for node component | +| controller.priorityClassName | string | `"system-cluster-critical"` | priorityClassName for controller component since this part is critical for cluster `system-cluster-critical` is default | +| controller.resources | object | `{}` | Sets compute resources for controller component | +| controller.tolerations | list | `[{"effect":"NoSchedule","key":"node-role.kubernetes.io/master","operator":"Equal","value":"true"}]` | Tolerations for controller component | +| crds.csi.volumeSnapshots.enabled | bool | `true` | Install Volume Snapshot CRDs | +| crds.enabled | bool | `true` | Disables the installation of all CRDs if set to false | +| global.analytics.enabled | bool | `true` | Enable OpenEBS analytics which help track engine traction and usage. | +| global.imagePullPolicy | string | `"IfNotPresent"` | Default pull policy for images | +| global.imagePullSecrets | list | `[]` | Default image pull secret for images | +| global.imageRegistry | string | `"docker.io"` | Default image registry for Images from DockerHub | +| global.k8sImageRegistry | string | `"registry.k8s.io"` | Default image registry for Images from Kubernetes (registry.k8s.io) | +| image.pullPolicy | string | `"IfNotPresent"` | Default image pull policy for node and controller components | +| image.registry | string | `""` | Image registry for rawfile-localpv (default is global.imageRegistry) | +| image.repository | string | `"openebs/rawfile-localpv"` | Image repository for rawfile-localpv | +| image.tag | string | `""` | Default image tag for node and controller components (uses AppVersion if empty) | +| imagePullSecrets | list | `[]` | Sets image pull secret while pulling images from a private registry | +| logFormat | string | `"json"` | Format of the logs (json, pretty) | +| logLevel | string | `"INFO"` | Level of the logs (DEBUG, INFO, etc.) | +| metrics.enabled | bool | `true` | Completely enable or disable metrics | +| metrics.port | int | `9100` | Sets metrics port | +| metrics.serviceMonitor.enabled | bool | `false` | Enables prometheus service monitor | +| metrics.serviceMonitor.interval | string | `"1m"` | Sets prometheus target interval | +| node.dataDirPath | string | `"/var/csi/rawfile"` | Data dir path for provisioner to be used by provisioner | +| node.driverRegistrar.image.registry | string | `""` | Image Registry for `csi-node-driver-registrar` | +| node.driverRegistrar.image.repository | string | `"sig-storage/csi-node-driver-registrar"` | Image Repository for `csi-node-driver-registrar` | +| node.driverRegistrar.image.tag | string | `"v2.13.0"` | Image Tag for `csi-node-driver-registrar` | +| node.externalProvisioner.image.registry | string | `""` | Image Registry for `csi-provisioner` | +| node.externalProvisioner.image.repository | string | `"sig-storage/csi-provisioner"` | Image Repository for `csi-provisioner` | +| node.externalProvisioner.image.tag | string | `"v5.2.0"` | Image Tag for `csi-provisioner` | +| node.externalSnapshotter.image.registry | string | `""` | Image Registry for `csi-snapshotter` | +| node.externalSnapshotter.image.repository | string | `"sig-storage/csi-snapshotter"` | Image Repository for `csi-snapshotter` | +| node.externalSnapshotter.image.tag | string | `"v8.2.1"` | Image Tag for `csi-snapshotter` | +| node.grpcWorkers | int | `10` | Number of gRPC workers for node component | +| node.image.pullPolicy | string | `""` | Overrides default image pull policy for node component | +| node.image.repository | string | `""` | Overrides default image repository for node component | +| node.image.tag | string | `""` | Overrides default image tag for node component | +| node.internalGRPC.port | int | `4500` | Port Number used for internal communication gRPC server | +| node.internalGRPC.workers | int | `10` | gRPC worker count used for internal communication | +| node.kubeletPath | string | `"/var/lib/kubelet"` | Kubelet path (Set to `/var/lib/k0s/kubelet` for k0s) | +| node.metadataDirPath | string | `"/var/local/openebs/rawfile/{{ .Release.Name }}/meta"` | Metadata dir path for rawfile volumes metadata and tasks store file | +| node.metrics.enabled | bool | `false` | | +| node.priorityClassName | string | `"system-node-critical"` | priorityClassName for node component since this part is critical for node `system-node-critical` is default | +| node.resources | object | `{}` | Sets compute resources for node component | +| node.snapshotController.image.registry | string | `""` | Image Registry for `snapshot-controller` | +| node.snapshotController.image.repository | string | `"sig-storage/snapshot-controller"` | Image Repository for `snapshot-controller` | +| node.snapshotController.image.tag | string | `"v8.2.1"` | Image Tag for `snapshot-controller` | +| node.tolerations | string | `nil` | Tolerations for node component | +| provisionerName | string | `"rawfile.csi.openebs.io"` | Name of the registered CSI Driver in the cluster | +| reservedCapacity | string | `""` | Used to reserve capacity on each node for data dir storage on each host (Supports percentage and size) [e.g. `25%` or `50GB` or `10MiB`] | +| snapshotClasses[0].deletionPolicy | string | `"Delete"` | Sets deletion policy for snapshots created using this class (Delete or Retain) | +| snapshotClasses[0].enabled | bool | `true` | Enable or disable SnapshotClass | +| snapshotClasses[0].isDefault | bool | `false` | Make the snapshot class as default | +| snapshotClasses[0].name | string | `"rawfile-localpv"` | Name of the SnapshotClass | +| storageClasses[0].allowVolumeExpansion | bool | `true` | volumes are able to expand/resize or not? | +| storageClasses[0].copyOnWrite | string | `""` | Enables CoW on storage class (defaults to autodetect) | +| storageClasses[0].enabled | bool | `true` | Enable or disable StorageClass | +| storageClasses[0].formatOptions | list | `[]` | Sets format options for filesystem volumes | +| storageClasses[0].freezeFs | string | `""` | Enables FreezeFS on storage class can be used to enable snapshotting of inused volumes when CoW is disabled/not supported (False by default) | +| storageClasses[0].fsType | string | `"ext4"` | Sets filesystem type for volumes (Currently supports `btrfs`, `xfs` and `ext4` [which is default]) | +| storageClasses[0].isDefault | bool | `false` | Make the storage class as default | +| storageClasses[0].mountOptions | list | `[]` | Sets mount options for filesystem volumes | +| storageClasses[0].name | string | `"rawfile-localpv"` | Name of the StorageClass | +| storageClasses[0].reclaimPolicy | string | `"Delete"` | Sets default reclaimPolicy for StorageClass volumes | +| storageClasses[0].thinProvision | string | `""` | Enables thin provisioning of volumes | +| storageClasses[0].volumeBindingMode | string | `"WaitForFirstConsumer"` | Sets volumeBindingMode for StorageClass | diff --git a/charts/rawfile-localpv/README.md.gotmpl b/charts/rawfile-localpv/README.md.gotmpl new file mode 100644 index 0000000..3d6cd28 --- /dev/null +++ b/charts/rawfile-localpv/README.md.gotmpl @@ -0,0 +1,20 @@ +{{ template "chart.header" . }} +{{ template "chart.deprecationWarning" . }} + +{{ template "chart.badgesSection" . }} + +{{ template "chart.description" . }} + +{{ template "chart.homepageLine" . }} + +{{ template "chart.maintainersSection" . }} + +{{ template "chart.sourcesSection" . }} + +{{ template "chart.requirementsSection" . }} + +## Install and Upgrades + +Please follow the [install guide](https://github.com/openebs/rawfile-localpv/tree/v{{ template "chart.version" . }}/docs/install-guide.md) + +{{ template "chart.valuesSection" . }} diff --git a/charts/rawfile-localpv/charts/crds/Chart.yaml b/charts/rawfile-localpv/charts/crds/Chart.yaml new file mode 100644 index 0000000..dc88bb6 --- /dev/null +++ b/charts/rawfile-localpv/charts/crds/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +description: 'A Helm chart that collects CustomResourceDefinitions (CRDs). ' +name: crds +version: 0.0.1 diff --git a/charts/rawfile-localpv/charts/crds/README.md b/charts/rawfile-localpv/charts/crds/README.md new file mode 100644 index 0000000..750ef8c --- /dev/null +++ b/charts/rawfile-localpv/charts/crds/README.md @@ -0,0 +1,13 @@ +# crds + +![Version: 0.0.1](https://img.shields.io/badge/Version-0.0.1-informational?style=flat-square) + +A Helm chart that collects CustomResourceDefinitions (CRDs). + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| csi.volumeSnapshots.annotations | object | `{}` | Annotations to be added to all CRDs | +| csi.volumeSnapshots.enabled | bool | `true` | Install Volume Snapshot CRDs | +| csi.volumeSnapshots.keep | bool | `true` | Keep CRDs on chart uninstall | diff --git a/charts/rawfile-localpv/charts/crds/templates/_helpers.tpl b/charts/rawfile-localpv/charts/crds/templates/_helpers.tpl new file mode 100644 index 0000000..6b2cbf1 --- /dev/null +++ b/charts/rawfile-localpv/charts/crds/templates/_helpers.tpl @@ -0,0 +1,19 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* + Adds extra annotations to CRDs. This targets two scenarios: preventing CRD recycling in case + the chart is removed; and adding custom annotations. + NOTE: This function assumes the element `metadata.annotations` already exists. + + Usage: + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} +*/}} + +{{- define "crds.extraAnnotations" -}} +{{- if .keep -}} +helm.sh/resource-policy: keep +{{ end }} +{{- with .annotations }} + {{- toYaml . }} +{{- end }} +{{- end -}} diff --git a/charts/rawfile-localpv/charts/crds/templates/csi-volume-snapshot-class.yaml b/charts/rawfile-localpv/charts/crds/templates/csi-volume-snapshot-class.yaml new file mode 100644 index 0000000..ba00aa3 --- /dev/null +++ b/charts/rawfile-localpv/charts/crds/templates/csi-volume-snapshot-class.yaml @@ -0,0 +1,155 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: | + Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshotClass + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: false + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/rawfile-localpv/charts/crds/templates/csi-volume-snapshot-content.yaml b/charts/rawfile-localpv/charts/crds/templates/csi-volume-snapshot-content.yaml new file mode 100644 index 0000000..96c4a98 --- /dev/null +++ b/charts/rawfile-localpv/charts/crds/templates/csi-volume-snapshot-content.yaml @@ -0,0 +1,499 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + oneOf: + - required: + - snapshotHandle + - required: + - volumeHandle + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + sourceVolumeMode: + description: SourceVolumeMode is the mode of the volume whose snapshot + is taken. Can be either “Filesystem” or “Block”. If not specified, + it indicates the source volume's mode is unknown. This field is + immutable. This field is an alpha field. + type: string + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: | + If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future. + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: | + Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: | + creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + volumeGroupSnapshotContentName: + description: VolumeGroupSnapshotContentName is the name of the VolumeGroupSnapshotContent + of which this VolumeSnapshotContent is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshotContent + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: | + If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future. + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: | + Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/rawfile-localpv/charts/crds/templates/csi-volume-snapshot.yaml b/charts/rawfile-localpv/charts/crds/templates/csi-volume-snapshot.yaml new file mode 100644 index 0000000..024eb0d --- /dev/null +++ b/charts/rawfile-localpv/charts/crds/templates/csi-volume-snapshot.yaml @@ -0,0 +1,400 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + oneOf: + - required: + - persistentVolumeClaimName + - required: + - volumeSnapshotContentName + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + volumeSnapshotClassName: + description: | + VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field. + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: | + boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + x-kubernetes-int-or-string: true + volumeGroupSnapshotName: + description: VolumeGroupSnapshotName is the name of the VolumeGroupSnapshot + of which this VolumeSnapshot is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshot + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: | + spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required. + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + volumeSnapshotClassName: + description: | + VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field. + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: | + boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/rawfile-localpv/charts/crds/values.yaml b/charts/rawfile-localpv/charts/crds/values.yaml new file mode 100644 index 0000000..d3bb538 --- /dev/null +++ b/charts/rawfile-localpv/charts/crds/values.yaml @@ -0,0 +1,10 @@ +csi: + volumeSnapshots: + # -- Install Volume Snapshot CRDs + enabled: true + # -- Keep CRDs on chart uninstall + keep: true + # -- Annotations to be added to all CRDs + annotations: {} + # Example for Argo CD to prevent CRDs from being recycled + # argocd.argoproj.io/sync-options: Prune=false diff --git a/charts/rawfile-localpv/templates/_helpers.tpl b/charts/rawfile-localpv/templates/_helpers.tpl new file mode 100644 index 0000000..8c34f79 --- /dev/null +++ b/charts/rawfile-localpv/templates/_helpers.tpl @@ -0,0 +1,122 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "rawfile-localpv.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +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 "rawfile-localpv.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "rawfile-localpv.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "rawfile-localpv.labels" -}} +helm.sh/chart: {{ include "rawfile-localpv.chart" . }} +{{ include "rawfile-localpv.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "rawfile-localpv.selectorLabels" -}} +app.kubernetes.io/name: {{ include "rawfile-localpv.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "rawfile-localpv.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "rawfile-localpv.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Some helpers to handle image global information +*/}} +{{- define "rawfile-localpv.controller-image-tag" -}} +{{- $imageTag := .Values.controller.image.tag | default .Values.image.tag | default (printf "v%s" .Chart.AppVersion) }} +{{- printf "%s" $imageTag }} +{{- end }} + +{{- define "rawfile-localpv.controller-image-repository" -}} +{{- printf "%s" .Values.controller.image.repository | default .Values.image.repository }} +{{- end }} + +{{- define "rawfile-localpv.controller-image" -}} +{{- $imageRegistry := .Values.image.registry | default .Values.global.imageRegistry }} +{{- printf "%s/%s:%s" $imageRegistry (include "rawfile-localpv.controller-image-repository" .) (include "rawfile-localpv.controller-image-tag" .) }} +{{- end }} + +{{- define "rawfile-localpv.controller-pull-policy" -}} +{{- printf "%s" (.Values.controller.image.pullPolicy | default .Values.image.pullPolicy | default .Values.global.imagePullPolicy) }} +{{- end }} + +{{- define "rawfile-localpv.controller-resources" -}} +{{- toYaml (.Values.controller.resources) }} +{{- end }} + +{{- define "rawfile-localpv.node-image-tag" -}} +{{- $imageTag := .Values.node.image.tag | default .Values.image.tag | default (printf "v%s" .Chart.AppVersion) }} +{{- printf "%s" $imageTag }} +{{- end }} + +{{- define "rawfile-localpv.node-image-registry" -}} +{{- printf "%s" .Values.image.registry | default .Values.global.imageRegistry }} +{{- end }} + +{{- define "rawfile-localpv.node-image-repository" -}} +{{- printf "%s" .Values.node.image.repository | default .Values.image.repository }} +{{- end }} + +{{- define "rawfile-localpv.node-image" -}} +{{- $imageRegistry := .Values.image.registry | default .Values.global.imageRegistry }} +{{- printf "%s/%s:%s" $imageRegistry (include "rawfile-localpv.node-image-repository" .) (include "rawfile-localpv.node-image-tag" .) }} +{{- end }} + +{{- define "rawfile-localpv.node-pull-policy" -}} +{{- printf "%s" (.Values.node.image.pullPolicy | default .Values.image.pullPolicy | default .Values.global.imagePullPolicy) }} +{{- end }} + +{{- define "rawfile-localpv.node-resources" -}} +{{- toYaml (.Values.node.resources) }} +{{- end }} + +{{- define "rawfile-localpv.node-kubelet-path" -}} +{{- printf "%s/" (.Values.node.kubeletPath | trimSuffix "/") -}} +{{- end }} + +{{- define "rawfile-localpv.metadata-dir-path" -}} +{{- tpl .Values.node.metadataDirPath . }} +{{- end }} diff --git a/charts/rawfile-localpv/templates/controller/service.yaml b/charts/rawfile-localpv/templates/controller/service.yaml new file mode 100644 index 0000000..5e8cd33 --- /dev/null +++ b/charts/rawfile-localpv/templates/controller/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-controller + labels: + {{- include "rawfile-localpv.labels" . | nindent 4 }} + component: controller +spec: + type: ClusterIP + selector: + {{- include "rawfile-localpv.selectorLabels" . | nindent 4 }} + component: controller + clusterIP: None diff --git a/charts/rawfile-localpv/templates/controller/statefulset.yaml b/charts/rawfile-localpv/templates/controller/statefulset.yaml new file mode 100644 index 0000000..5c6fef1 --- /dev/null +++ b/charts/rawfile-localpv/templates/controller/statefulset.yaml @@ -0,0 +1,99 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-controller +spec: + replicas: 1 + serviceName: {{ include "rawfile-localpv.fullname" . }} + selector: + matchLabels: &selectorLabels + {{- include "rawfile-localpv.selectorLabels" . | nindent 6 }} + component: controller + template: + metadata: + labels: *selectorLabels + spec: + serviceAccount: {{ include "rawfile-localpv.fullname" . }}-driver + priorityClassName: {{ .Values.controller.priorityClassName }} + tolerations: + {{- .Values.controller.tolerations | toYaml | nindent 8 }} + volumes: + - name: socket-dir + emptyDir: {} + containers: + - name: csi-driver + image: "{{ include "rawfile-localpv.controller-image" . }}" + imagePullPolicy: "{{ include "rawfile-localpv.controller-pull-policy" . }}" + args: + - csi-driver + - --enable-metrics=false + env: + - name: PROVISIONER_NAME + value: "{{ .Values.provisionerName }}" + - name: CSI_DRIVER__ENDPOINT + value: unix:///csi/csi.sock + - name: CSI_DRIVER__NODE_ID + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: NAMESPACE + value: {{ .Release.Namespace }} + - name: LOG_LEVEL + value: {{ .Values.logLevel }} + - name: LOG_FORMAT + value: {{ .Values.logFormat }} + - name: CSI_DRIVER__PLUGIN_TYPE + value: controller + {{- if .Values.reservedCapacity }} + - name: RESERVED_CAPACITY + value: {{ .Values.reservedCapacity | toString | quote }} + {{- end }} + {{- if .Values.capacityOverride }} + - name: CAPACITY_OVERRIDE + value: {{ .Values.capacityOverride | toString | quote }} + {{- end }} + - name: CSI_DRIVER__GRPC_WORKERS + value: {{ .Values.controller.grpcWorkers | toString | quote }} + - name: GA_ENABLED + value: "{{ .Values.global.analytics.enabled }}" + {{- if .Values.global.analytics.gaId }} + - name: GA_ID + value: {{ .Values.global.analytics.gaId | quote }} + {{- end }} + {{- if .Values.global.analytics.gaKey }} + - name: GA_KEY + value: {{ .Values.global.analytics.gaKey | quote }} + {{- end }} + - name: CSI_DRIVER__INTERNAL_PORT + value: {{ .Values.node.internalGRPC.port | toString | quote }} + - name: CSI_DRIVER__NODE_DS + value: {{ include "rawfile-localpv.fullname" . }}-node + {{- if .Values.auth.enabled }} + - name: CSI_DRIVER__INTERNAL_SIGNATURE + valueFrom: + secretKeyRef: + name: {{ include "rawfile-localpv.fullname" . }}-secrets + key: internal-signature + {{- end }} + volumeMounts: + - name: socket-dir + mountPath: /csi + ports: + - name: csi-probe + containerPort: 9808 + resources: + {{- include "rawfile-localpv.controller-resources" . | nindent 12 }} + - name: external-resizer + image: {{ printf "%s/%s:%s" (.Values.controller.externalResizer.image.registry | default .Values.global.k8sImageRegistry) .Values.controller.externalResizer.image.repository .Values.controller.externalResizer.image.tag }} + imagePullPolicy: IfNotPresent + args: + - "--csi-address=$(ADDRESS)" + - "--handle-volume-inuse-error=false" + - "--timeout=30s" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi diff --git a/charts/rawfile-localpv/templates/driver.yaml b/charts/rawfile-localpv/templates/driver.yaml new file mode 100644 index 0000000..0e1d18c --- /dev/null +++ b/charts/rawfile-localpv/templates/driver.yaml @@ -0,0 +1,11 @@ +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: {{ .Values.provisionerName }} +spec: + attachRequired: false + podInfoOnMount: true + fsGroupPolicy: File + storageCapacity: true + volumeLifecycleModes: + - Persistent diff --git a/charts/rawfile-localpv/templates/node-plugin/daemonset.yaml b/charts/rawfile-localpv/templates/node-plugin/daemonset.yaml new file mode 100644 index 0000000..473ce97 --- /dev/null +++ b/charts/rawfile-localpv/templates/node-plugin/daemonset.yaml @@ -0,0 +1,220 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-node +spec: + updateStrategy: + rollingUpdate: + maxUnavailable: "100%" + selector: + matchLabels: &selectorLabels + {{- include "rawfile-localpv.selectorLabels" . | nindent 6 }} + component: node + template: + metadata: + labels: *selectorLabels + spec: + serviceAccount: {{ include "rawfile-localpv.fullname" . }}-driver + priorityClassName: {{ .Values.node.priorityClassName }} + tolerations: + {{- .Values.node.tolerations | toYaml | nindent 8 }} + volumes: + - name: registration-dir + hostPath: + path: {{ include "rawfile-localpv.node-kubelet-path" . }}plugins_registry + type: Directory + - name: socket-dir + hostPath: + path: {{ include "rawfile-localpv.node-kubelet-path" . }}plugins/rawfile-localpv + type: DirectoryOrCreate + - name: mountpoint-dir + hostPath: + path: {{ include "rawfile-localpv.node-kubelet-path" . }} + type: DirectoryOrCreate + - name: data-dir + hostPath: + path: {{ .Values.node.dataDirPath }} + type: DirectoryOrCreate + - name: metadata-dir + hostPath: + path: {{ include "rawfile-localpv.metadata-dir-path" . }} + type: DirectoryOrCreate + - name: device + hostPath: + path: /dev + type: Directory + containers: + - name: csi-driver + image: "{{ include "rawfile-localpv.node-image" . }}" + imagePullPolicy: "{{ include "rawfile-localpv.node-pull-policy" . }}" + securityContext: + privileged: true + env: + - name: PROVISIONER_NAME + value: "{{ .Values.provisionerName }}" + - name: CSI_DRIVER__ENDPOINT + value: unix:///csi/csi.sock + - name: CSI_DRIVER__NODE_ID + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: CSI_DRIVER__ENABLE_METRICS + value: {{ .Values.metrics.enabled | toString | quote }} + - name: CSI_DRIVER__METRICS_PORT + value: {{ .Values.metrics.port | toString | quote }} + - name: CSI_DRIVER__METADATA_DIR + value: {{ include "rawfile-localpv.metadata-dir-path" . }} + - name: NAMESPACE + value: {{ .Release.Namespace }} + - name: LOG_LEVEL + value: {{ .Values.logLevel }} + - name: LOG_FORMAT + value: {{ .Values.logFormat }} + - name: CSI_DRIVER__PLUGIN_TYPE + value: node + {{- if .Values.reservedCapacity }} + - name: RESERVED_CAPACITY + value: {{ .Values.reservedCapacity | toString | quote }} + {{- end }} + {{- if .Values.capacityOverride }} + - name: CAPACITY_OVERRIDE + value: {{ .Values.capacityOverride | toString | quote }} + {{- end }} + - name: CSI_DRIVER__GRPC_WORKERS + value: {{ .Values.node.grpcWorkers | toString | quote }} + - name: GA_ENABLED + value: "{{ .Values.global.analytics.enabled }}" + {{- if .Values.global.analytics.gaId }} + - name: GA_ID + value: {{ .Values.global.analytics.gaId | quote }} + {{- end }} + {{- if .Values.global.analytics.gaKey }} + - name: GA_KEY + value: {{ .Values.global.analytics.gaKey | quote }} + {{- end }} + - name: CSI_DRIVER__INTERNAL_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: CSI_DRIVER__INTERNAL_PORT + value: {{ .Values.node.internalGRPC.port | toString | quote }} + - name: CSI_DRIVER__INTERNAL_GRPC_WORKERS + value: {{ .Values.node.internalGRPC.workers | toString | quote }} + - name: CSI_DRIVER__NODE_DS + value: {{ include "rawfile-localpv.fullname" . }}-node + {{- if .Values.auth.enabled }} + - name: CSI_DRIVER__INTERNAL_SIGNATURE + valueFrom: + secretKeyRef: + name: {{ include "rawfile-localpv.fullname" . }}-secrets + key: internal-signature + {{- end }} + ports: + - name: metrics + containerPort: {{ .Values.metrics.port }} + - name: csi-probe + containerPort: 9808 + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: mountpoint-dir + mountPath: {{ include "rawfile-localpv.node-kubelet-path" . }} + mountPropagation: "Bidirectional" + - name: data-dir + mountPath: /data + - name: metadata-dir + mountPath: {{ include "rawfile-localpv.metadata-dir-path" . }} + - name: device + mountPath: /dev + resources: + {{- include "rawfile-localpv.controller-resources" . | nindent 12 }} + - name: node-driver-registrar + image: {{ printf "%s/%s:%s" (.Values.node.driverRegistrar.image.registry | default .Values.global.k8sImageRegistry) .Values.node.driverRegistrar.image.repository .Values.node.driverRegistrar.image.tag }} + imagePullPolicy: IfNotPresent + args: + - --csi-address=$(ADDRESS) + - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH) + - --health-port=9809 + env: + - name: ADDRESS + value: /csi/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: {{ include "rawfile-localpv.node-kubelet-path" . }}plugins/rawfile-localpv/csi.sock + ports: + - containerPort: 9809 + name: healthz + livenessProbe: + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 5 + timeoutSeconds: 5 + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + resources: + limits: + cpu: 500m + memory: 100Mi + requests: + cpu: 10m + memory: 100Mi + - name: external-provisioner + image: {{ printf "%s/%s:%s" (.Values.node.externalProvisioner.image.registry | default .Values.global.k8sImageRegistry) .Values.node.externalProvisioner.image.repository .Values.node.externalProvisioner.image.tag }} + imagePullPolicy: IfNotPresent + args: + - "--csi-address=$(ADDRESS)" + - "--feature-gates=Topology=true" + - "--strict-topology" + - "--immediate-topology=false" + - "--timeout=120s" + - "--enable-capacity=true" + - "--capacity-for-immediate-binding=true" + - "--capacity-ownerref-level=1" # DaemonSet + - "--node-deployment=true" + - "--extra-create-metadata=true" + env: + - name: ADDRESS + value: /csi/csi.sock + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: external-snapshotter + image: {{ printf "%s/%s:%s" (.Values.node.externalSnapshotter.image.registry | default .Values.global.k8sImageRegistry) .Values.node.externalSnapshotter.image.repository .Values.node.externalSnapshotter.image.tag }} + imagePullPolicy: IfNotPresent + args: + - "--csi-address=$(ADDRESS)" + - "--node-deployment=true" + - "--extra-create-metadata=true" + env: + - name: ADDRESS + value: /csi/csi.sock + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: snapshot-controller + args: + - "--v=2" + - "--enable-distributed-snapshotting=true" + image: {{ printf "%s/%s:%s" (.Values.node.snapshotController.image.registry | default .Values.global.k8sImageRegistry) .Values.node.snapshotController.image.repository .Values.node.snapshotController.image.tag }} + imagePullPolicy: IfNotPresent diff --git a/charts/rawfile-localpv/templates/node-plugin/service.yaml b/charts/rawfile-localpv/templates/node-plugin/service.yaml new file mode 100644 index 0000000..9b39e74 --- /dev/null +++ b/charts/rawfile-localpv/templates/node-plugin/service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-node + labels: + {{- include "rawfile-localpv.labels" . | nindent 4 }} + component: node +spec: + type: ClusterIP + ports: + - name: metrics + port: {{ .Values.metrics.port }} + targetPort: metrics + protocol: TCP + - name: internal + port: {{ .Values.node.internalGRPC.port }} + protocol: TCP + selector: + {{- include "rawfile-localpv.selectorLabels" . | nindent 4 }} + component: node diff --git a/charts/rawfile-localpv/templates/node-plugin/servicemonitor.yaml b/charts/rawfile-localpv/templates/node-plugin/servicemonitor.yaml new file mode 100644 index 0000000..3d10b91 --- /dev/null +++ b/charts/rawfile-localpv/templates/node-plugin/servicemonitor.yaml @@ -0,0 +1,25 @@ +{{- if .Values.metrics.enabled }} +{{- if .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-node + labels: + {{- include "rawfile-localpv.labels" . | nindent 4 }} +spec: + endpoints: + - port: metrics + path: /metrics + {{- with .Values.metrics.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + jobLabel: "helm.sh/chart" + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "rawfile-localpv.selectorLabels" . | nindent 6 }} + component: node +{{- end }} +{{- end }} diff --git a/charts/rawfile-localpv/templates/rbac.yaml b/charts/rawfile-localpv/templates/rbac.yaml new file mode 100644 index 0000000..4436f92 --- /dev/null +++ b/charts/rawfile-localpv/templates/rbac.yaml @@ -0,0 +1,191 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-driver +imagePullSecrets: + {{- toYaml .Values.imagePullSecrets | nindent 2 }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-provisioner +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csistoragecapacities"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: [""] + resources: ["pods", "pods/log"] + verbs: ["get"] + - apiGroups: ["apps"] + resources: ["daemonsets"] + verbs: ["get"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-provisioner +subjects: + - kind: ServiceAccount + name: {{ include "rawfile-localpv.fullname" . }}-driver + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ include "rawfile-localpv.fullname" . }}-provisioner + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-broker +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-broker +subjects: + - kind: ServiceAccount + name: {{ include "rawfile-localpv.fullname" . }}-driver + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ include "rawfile-localpv.fullname" . }}-broker + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-resizer +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["patch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-resizer +subjects: + - kind: ServiceAccount + name: {{ include "rawfile-localpv.fullname" . }}-driver + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ include "rawfile-localpv.fullname" . }}-resizer + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-snapshotter +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update", "patch", "delete"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-snapshotter +subjects: + - kind: ServiceAccount + name: {{ include "rawfile-localpv.fullname" . }}-driver + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ include "rawfile-localpv.fullname" . }}-snapshotter + apiGroup: rbac.authorization.k8s.io +--- +{{- if .Values.global.analytics.enabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-analytics +rules: + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["get"] + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["create", "get", "update", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "rawfile-localpv.fullname" . }}-analytics +subjects: + - kind: ServiceAccount + name: {{ include "rawfile-localpv.fullname" . }}-driver + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ include "rawfile-localpv.fullname" . }}-analytics + apiGroup: rbac.authorization.k8s.io +--- +{{- end }} diff --git a/charts/rawfile-localpv/templates/secret.yaml b/charts/rawfile-localpv/templates/secret.yaml new file mode 100644 index 0000000..6d3f78f --- /dev/null +++ b/charts/rawfile-localpv/templates/secret.yaml @@ -0,0 +1,19 @@ +{{- $secret_name := printf "%s-secrets" (include "rawfile-localpv.fullname" .) }} +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "rawfile-localpv.labels" . | nindent 4 }} + name: {{ $secret_name }} +type: Opaque +data: + {{- $old_sec := lookup "v1" "Secret" .Release.Namespace $secret_name }} + {{- if not .Values.auth.token }} + {{- if or (not $old_sec) (not $old_sec.data) }} + internal-signature: {{ randAlphaNum 32 | b64enc }} + {{- else }} + internal-signature: {{ index $old_sec.data "internal-signature" }} + {{- end }} + {{- else }} + internal-signature: {{ .Values.auth.token }} + {{- end }} diff --git a/charts/rawfile-localpv/templates/snapshotclass.yaml b/charts/rawfile-localpv/templates/snapshotclass.yaml new file mode 100644 index 0000000..72eb256 --- /dev/null +++ b/charts/rawfile-localpv/templates/snapshotclass.yaml @@ -0,0 +1,16 @@ +{{- $vals := .Values }} +{{- range $class := .Values.snapshotClasses }} +{{- if $class.enabled }} +apiVersion: snapshot.storage.k8s.io/v1 +kind: VolumeSnapshotClass +metadata: + name: {{ $class.name }} + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-weight": "-5" + {{- if $class.isDefault }}snapshot.storage.kubernetes.io/is-default-class: "true"{{ end }} +driver: {{ $vals.provisionerName }} +deletionPolicy: {{ $class.deletionPolicy }} +--- +{{- end }} +{{- end }} diff --git a/charts/rawfile-localpv/templates/storageclass.yaml b/charts/rawfile-localpv/templates/storageclass.yaml new file mode 100644 index 0000000..763d6a3 --- /dev/null +++ b/charts/rawfile-localpv/templates/storageclass.yaml @@ -0,0 +1,26 @@ +{{- $vals := .Values }} +{{- range $class := .Values.storageClasses }} +{{- if $class.enabled }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ $class.name }} + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-weight": "-5" + {{- if $class.isDefault }}storageclass.kubernetes.io/is-default-class: "true"{{ end }} +provisioner: {{ $vals.provisionerName }} +reclaimPolicy: {{ $class.reclaimPolicy }} +volumeBindingMode: {{ $class.volumeBindingMode }} +allowVolumeExpansion: {{ $class.allowVolumeExpansion }} +mountOptions: + {{- toYaml ($class.mountOptions | default (list)) | nindent 2 }} +parameters: + csi.storage.k8s.io/fstype: {{ $class.fsType | default "ext4" }} + thinProvision: {{ $class.thinProvision | default "false" | toString | quote }} + formatOptions: {{ ($class.formatOptions | default (list)) | join " " | quote }} + copyOnWrite: {{ $class.copyOnWrite | default "false" | toString | quote }} + freezeFs: {{ $class.freezeFs | default "false" | toString | quote }} +--- +{{- end }} +{{- end }} diff --git a/charts/rawfile-localpv/values.yaml b/charts/rawfile-localpv/values.yaml new file mode 100644 index 0000000..d37ee7c --- /dev/null +++ b/charts/rawfile-localpv/values.yaml @@ -0,0 +1,221 @@ +# -- Name of the registered CSI Driver in the cluster +provisionerName: "rawfile.csi.openebs.io" + +# -- Level of the logs (DEBUG, INFO, etc.) +logLevel: INFO +# -- Format of the logs (json, pretty) +logFormat: json + +# -- Used to reserve capacity on each node for data dir storage on each host (Supports percentage and size) [e.g. `25%` or `50GB` or `10MiB`] +reservedCapacity: "" +# -- Overrides total capacity of the storage for data dir storage on each host (Support size values) [e.g. `50GB` or `10MiB`] +capacityOverride: "" + +auth: + # -- Enables authentication for internal gRPC server + enabled: true + # -- Sets authentication token for internal gRPC server, will generate one if nothing provided + token: "" + +global: + # -- Default image registry for Images from DockerHub + imageRegistry: docker.io + # -- Default image registry for Images from Kubernetes (registry.k8s.io) + k8sImageRegistry: registry.k8s.io + # -- Default pull policy for images + imagePullPolicy: IfNotPresent + # -- Default image pull secret for images + imagePullSecrets: [] + analytics: + # -- Enable OpenEBS analytics which help track engine traction and usage. + enabled: true + +image: + # -- Image registry for rawfile-localpv (default is global.imageRegistry) + registry: "" + # -- Image repository for rawfile-localpv + repository: openebs/rawfile-localpv + # -- Default image tag for node and controller components (uses AppVersion if empty) + tag: "" + # -- Default image pull policy for node and controller components + pullPolicy: IfNotPresent + +controller: + image: + # -- Overrides default image repository for node component + repository: "" + # -- Overrides default image tag for node component + tag: "" + # -- Overrides default image pull policy for node component + pullPolicy: "" + + externalResizer: + image: + # -- Image registry for `csi-resizer` + registry: "" + # -- Image Repository for `csi-resizer` + repository: sig-storage/csi-resizer + # -- Image tag for `csi-resizer` + tag: v1.13.2 + + # -- Sets compute resources for controller component + resources: + {} + # limits: + # cpu: 1 + # memory: 100Mi + # requests: + # cpu: 10m + # memory: 100Mi + + # -- priorityClassName for controller component since this part is critical for cluster `system-cluster-critical` is default + priorityClassName: system-cluster-critical + + # -- Tolerations for controller component + tolerations: + - key: "node-role.kubernetes.io/master" + operator: Equal + value: "true" + effect: NoSchedule + + # -- Number of gRPC workers for controller component + grpcWorkers: 10 + +node: + image: + # -- Overrides default image repository for node component + repository: "" + # -- Overrides default image tag for node component + tag: "" + # -- Overrides default image pull policy for node component + pullPolicy: "" + + driverRegistrar: + image: + # -- Image Registry for `csi-node-driver-registrar` + registry: "" + # -- Image Repository for `csi-node-driver-registrar` + repository: sig-storage/csi-node-driver-registrar + # -- Image Tag for `csi-node-driver-registrar` + tag: v2.13.0 + + externalProvisioner: + image: + # -- Image Registry for `csi-provisioner` + registry: "" + # -- Image Repository for `csi-provisioner` + repository: sig-storage/csi-provisioner + # -- Image Tag for `csi-provisioner` + tag: v5.2.0 + + externalSnapshotter: + image: + # -- Image Registry for `csi-snapshotter` + registry: "" + # -- Image Repository for `csi-snapshotter` + repository: sig-storage/csi-snapshotter + # -- Image Tag for `csi-snapshotter` + tag: v8.2.1 + + snapshotController: + image: + # -- Image Registry for `snapshot-controller` + registry: "" + # -- Image Repository for `snapshot-controller` + repository: sig-storage/snapshot-controller + # -- Image Tag for `snapshot-controller` + tag: v8.2.1 + + # -- Data dir path for provisioner to be used by provisioner + dataDirPath: /var/csi/rawfile + + # -- Metadata dir path for rawfile volumes metadata and tasks store file + metadataDirPath: /var/local/openebs/rawfile/{{ .Release.Name }}/meta + + # -- Kubelet path (Set to `/var/lib/k0s/kubelet` for k0s) + kubeletPath: /var/lib/kubelet + + # -- Sets compute resources for node component + resources: + {} + # limits: + # cpu: 1 + # memory: 100Mi + # requests: + # cpu: 10m + # memory: 100Mi + metrics: + enabled: false + + # -- priorityClassName for node component since this part is critical for node `system-node-critical` is default + priorityClassName: system-node-critical + + # -- Tolerations for node component + tolerations: + + # -- Number of gRPC workers for node component + grpcWorkers: 10 + + internalGRPC: + # -- Port Number used for internal communication gRPC server + port: 4500 + # --gRPC worker count used for internal communication + workers: 10 + +# -- Sets image pull secret while pulling images from a private registry +imagePullSecrets: [] + +metrics: + # -- Completely enable or disable metrics + enabled: true + # -- Sets metrics port + port: 9100 + serviceMonitor: + # -- Enables prometheus service monitor + enabled: false + # -- Sets prometheus target interval + interval: 1m + +storageClasses: + - # -- Name of the StorageClass + name: rawfile-localpv + # -- Enable or disable StorageClass + enabled: true + # -- Sets volumeBindingMode for StorageClass + volumeBindingMode: WaitForFirstConsumer + # -- Make the storage class as default + isDefault: false + # -- volumes are able to expand/resize or not? + allowVolumeExpansion: true + # -- Sets default reclaimPolicy for StorageClass volumes + reclaimPolicy: Delete + # -- Sets filesystem type for volumes (Currently supports `btrfs`, `xfs` and `ext4` [which is default]) + fsType: ext4 + # -- Enables thin provisioning of volumes + thinProvision: "" + # -- Sets mount options for filesystem volumes + mountOptions: [] + # -- Sets format options for filesystem volumes + formatOptions: [] + # -- Enables CoW on storage class (defaults to autodetect) + copyOnWrite: "" + # -- Enables FreezeFS on storage class can be used to enable snapshotting of inused volumes when CoW is disabled/not supported (False by default) + freezeFs: "" + +snapshotClasses: + - # -- Name of the SnapshotClass + name: rawfile-localpv + # -- Enable or disable SnapshotClass + enabled: true + # -- Sets deletion policy for snapshots created using this class (Delete or Retain) + deletionPolicy: Delete + # -- Make the snapshot class as default + isDefault: false + +crds: + # -- Disables the installation of all CRDs if set to false + enabled: true + csi: + volumeSnapshots: + # -- Install Volume Snapshot CRDs + enabled: true diff --git a/charts/zfs-localpv/Chart.lock b/charts/zfs-localpv/Chart.lock new file mode 100644 index 0000000..4ed2256 --- /dev/null +++ b/charts/zfs-localpv/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: crds + repository: "" + version: 2.9.0 +digest: sha256:0032f71831e5ecceb72f7968521d3385a4e9d078a100f03d913014de19df2800 +generated: "2025-11-18T08:12:41.465080026Z" diff --git a/charts/zfs-localpv/Chart.yaml b/charts/zfs-localpv/Chart.yaml new file mode 100644 index 0000000..1e812c2 --- /dev/null +++ b/charts/zfs-localpv/Chart.yaml @@ -0,0 +1,22 @@ +apiVersion: v2 +appVersion: 2.9.0 +dependencies: +- condition: crds.enabled + name: crds + repository: "" + version: 2.9.0 +description: Helm chart for CSI Driver for dynamic provisioning of ZFS Persistent + Local Volumes. For instructions on how to use this helm chart, see - https://openebs.github.io/zfs-localpv/ +home: https://openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- filesystem +- ZFS +- Local Persistent Volumes +- storage +name: zfs-localpv +sources: +- https://github.com/openebs/zfs-localpv +version: 2.9.0 diff --git a/charts/zfs-localpv/README.md b/charts/zfs-localpv/README.md new file mode 100644 index 0000000..2258508 --- /dev/null +++ b/charts/zfs-localpv/README.md @@ -0,0 +1,124 @@ + +# OpenEBS Local PV ZFS Provisioner + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Chart Lint and Test](https://github.com/openebs/zfs-localpv/workflows/Chart%20Lint%20and%20Test/badge.svg) +![Release Charts](https://github.com/openebs/zfs-localpv/workflows/Release%20Charts/badge.svg?branch=develop) + +A Helm chart for openebs localpv zfs provisioner. This chart bootstraps OpenEBS ZFS LocalPV provisioner deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + + +**Homepage:** + +## Get Repo Info + +```console +helm repo add openebs-zfslocalpv https://openebs.github.io/zfs-localpv +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +Please visit the [link](https://openebs.github.io/zfs-localpv/) for install instructions via helm3. + +```console +# Helm +$ helm install [RELEASE_NAME] openebs-zfslocalpv/zfs-localpv +``` + +**Note:** If moving from the operator to helm +- Make sure the namespace provided in the helm install command is same as `OPENEBS_NAMESPACE` (by default it is `openebs`) env in the controller deployment. +- Before installing, clean up the stale deployment and daemonset from `openebs` namespace using the below commands +```sh +kubectl delete deploy openebs-zfs-controller -n openebs +kubectl delete ds openebs-zfs-node -n openebs +``` + + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +# Helm +$ helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +# Helm +$ helm upgrade [RELEASE_NAME] [CHART] --install +``` + +## Configuration + +The following table lists the configurable parameters of the OpenEBS ZFS Localpv chart and their default values. + +## Values + +| Key | Type | Default Value | Description | +|----------------------------------------------------------------------|--------|-----------------------------|-------------------------------------------------------------------------------------------------------| +| `analytics.enabled` | bool | `true` | Enables or disables analytics reporting for the chart. | +| `analytics.installerType` | string | `"zfs-localpv-helm"` | Specifies the installer type for analytics. | +| `backupGC.enabled` | bool | `false` | Enables or disables garbage collection for backups. | +| `crds.csi.volumeSnapshots.enabled` | bool | `true` | Enables or disables the installation of Volume Snapshot CRDs. | +| `crds.zfsLocalPv.enabled` | bool | `true` | Enables or disables the installation of ZFS Local Persistent Volume CRDs. | +| `enableHelmMetaLabels` | bool | `true` | Adds Helm-specific metadata labels to the components. | +| `feature.storageCapacity` | bool | `true` | Enables or disables storage capacity tracking feature. | +| `imagePullSecrets` | list | `[]` | List of secrets to use when pulling images from private registries. | +| `loggingLabels."openebs.io/logging"` | string | `"true"` | Enables or disables logging for OpenEBS components. | +| `rbac.pspEnabled` | bool | `false` | Enables or disables the creation of PodSecurityPolicy resources. | +| `role` | string | `"openebs-zfs"` | Specifies the role for the OpenEBS ZFS component. | +| `serviceAccount.zfsController.create` | bool | `true` | Specifies whether a service account should be created for the ZFS controller. | +| `serviceAccount.zfsController.name` | string | `"openebs-zfs-controller-sa"` | The name of the service account to use for the ZFS controller. | +| `serviceAccount.zfsNode.create` | bool | `true` | Specifies whether a service account should be created for the ZFS node. | +| `serviceAccount.zfsNode.name` | string | `"openebs-zfs-node-sa"` | The name of the service account to use for the ZFS node. | +| `zfs.bin` | string | `"zfs"` | Path to the ZFS binary. | +| `zfsController.additionalVolumes` | list | `[]` | Additional volumes to mount into the ZFS controller pods. | +| `zfsController.annotations` | map | `{}` | Annotations to add to the ZFS controller pods. | +| `zfsController.componentName` | string | `"openebs-zfs-controller"` | Name of the ZFS controller component. | +| `zfsController.initContainers` | list | `[]` | List of init containers to run before the ZFS controller pods. | +| `zfsController.nodeSelector` | map | `{}` | Node selector for scheduling ZFS controller pods. | +| `zfsController.podAnnotations` | map | `{}` | Annotations to add to the ZFS controller pods. | +| `zfsController.podLabels.name` | string | `"openebs-zfs-controller"` | Labels to add to the ZFS controller pods. | +| `zfsController.priorityClass.create` | bool | `true` | Specifies whether to create a priority class for the ZFS controller pods. | +| `zfsController.priorityClass.name` | string | `"zfs-csi-controller-critical"` | The name of the priority class to use for the ZFS controller pods. | +| `zfsController.provisioner.extraArgs` | list | `[]` | Additional arguments to pass to the CSI provisioner. | +| `zfsController.provisioner.image.pullPolicy` | string | `"IfNotPresent"` | Image pull policy for the CSI provisioner. | +| `zfsController.provisioner.image.registry` | string | `"registry.k8s.io/"` | Image registry for the CSI provisioner. | +| `zfsController.provisioner.image.repository` | string | `"sig-storage/csi-provisioner"` | Image repository for the CSI provisioner. | +| `zfsController.provisioner.image.tag` | string | `"v5.2.0"` | Image tag for the CSI provisioner. | +| `zfsController.provisioner.name` | string | `"csi-provisioner"` | Name of the CSI provisioner container. | +| `zfsController.replicas` | int | `1` | Number of replicas for the ZFS controller deployment. | +| `zfsController.resizer.extraArgs` | list | `[]` | Additional arguments to pass to the CSI resizer. | +| `zfsController.resizer.image.pullPolicy` | string | `"IfNotPresent"` | Image pull policy for the CSI resizer. | +| `zfsController.resizer.image.registry` | string | `"registry.k8s.io/"` | Image registry for the CSI resizer. | +| `zfsController.resizer.image.repository` | string | `"sig-storage/csi-resizer"` | Image repository for the CSI resizer. | +| `zfsController.resizer.image.tag` | string | `"v1.13.2"` | Image tag for the CSI resizer. | +| `zfsController.resizer.name` | string | `"csi-resizer"` | Name of the CSI resizer container. | +| `zfsController.resources` | map | `{}` | Resource requests and limits for the ZFS controller pods. | +| `zfsController.securityContext` | map | `{}` | Security context for the ZFS controller pods. | +| `zfsController.snapshotController.extraArgs` | list | `[]` | Additional arguments to pass to the snapshot controller. | +| `zfsController.snapshotController.image.pullPolicy` | string | `"IfNotPresent"` | Image pull policy for the snapshot controller. | +| `zfsController.snapshotController.image.registry` | string | `"registry.k8s.io/"` | Image registry for the snapshot controller. | +| `zfsController.snapshotController.image.repository` | string | `"sig-storage/snapshot-controller"` | Image repository for the snapshot controller. | +| `zfsController.snapshotController.image.tag` | string | `"v8.2.0"` | Image tag for the snapshot controller. + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml openebs/zfs-localpv +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/charts/zfs-localpv/charts/crds/.helmignore b/charts/zfs-localpv/charts/crds/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/zfs-localpv/charts/crds/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/zfs-localpv/charts/crds/Chart.yaml b/charts/zfs-localpv/charts/crds/Chart.yaml new file mode 100644 index 0000000..47e66d2 --- /dev/null +++ b/charts/zfs-localpv/charts/crds/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +description: A Helm chart that collects CustomResourceDefinitions (CRDs) from zfs-localpv. +name: crds +version: 2.9.0 diff --git a/charts/zfs-localpv/charts/crds/templates/_helpers.tpl b/charts/zfs-localpv/charts/crds/templates/_helpers.tpl new file mode 100644 index 0000000..6b2cbf1 --- /dev/null +++ b/charts/zfs-localpv/charts/crds/templates/_helpers.tpl @@ -0,0 +1,19 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* + Adds extra annotations to CRDs. This targets two scenarios: preventing CRD recycling in case + the chart is removed; and adding custom annotations. + NOTE: This function assumes the element `metadata.annotations` already exists. + + Usage: + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} +*/}} + +{{- define "crds.extraAnnotations" -}} +{{- if .keep -}} +helm.sh/resource-policy: keep +{{ end }} +{{- with .annotations }} + {{- toYaml . }} +{{- end }} +{{- end -}} diff --git a/charts/zfs-localpv/charts/crds/templates/csi-volume-snapshot-class.yaml b/charts/zfs-localpv/charts/crds/templates/csi-volume-snapshot-class.yaml new file mode 100644 index 0000000..ba00aa3 --- /dev/null +++ b/charts/zfs-localpv/charts/crds/templates/csi-volume-snapshot-class.yaml @@ -0,0 +1,155 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: | + Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshotClass + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: false + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/zfs-localpv/charts/crds/templates/csi-volume-snapshot-content.yaml b/charts/zfs-localpv/charts/crds/templates/csi-volume-snapshot-content.yaml new file mode 100644 index 0000000..96c4a98 --- /dev/null +++ b/charts/zfs-localpv/charts/crds/templates/csi-volume-snapshot-content.yaml @@ -0,0 +1,499 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + oneOf: + - required: + - snapshotHandle + - required: + - volumeHandle + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + sourceVolumeMode: + description: SourceVolumeMode is the mode of the volume whose snapshot + is taken. Can be either “Filesystem” or “Block”. If not specified, + it indicates the source volume's mode is unknown. This field is + immutable. This field is an alpha field. + type: string + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: | + If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future. + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: | + Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: | + creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + volumeGroupSnapshotContentName: + description: VolumeGroupSnapshotContentName is the name of the VolumeGroupSnapshotContent + of which this VolumeSnapshotContent is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshotContent + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: | + If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future. + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: | + Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/zfs-localpv/charts/crds/templates/csi-volume-snapshot.yaml b/charts/zfs-localpv/charts/crds/templates/csi-volume-snapshot.yaml new file mode 100644 index 0000000..024eb0d --- /dev/null +++ b/charts/zfs-localpv/charts/crds/templates/csi-volume-snapshot.yaml @@ -0,0 +1,400 @@ +{{- if .Values.csi.volumeSnapshots.enabled -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + {{- include "crds.extraAnnotations" .Values.csi.volumeSnapshots | nindent 4 }} + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + oneOf: + - required: + - persistentVolumeClaimName + - required: + - volumeSnapshotContentName + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + volumeSnapshotClassName: + description: | + VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field. + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: | + boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + x-kubernetes-int-or-string: true + volumeGroupSnapshotName: + description: VolumeGroupSnapshotName is the name of the VolumeGroupSnapshot + of which this VolumeSnapshot is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshot + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + properties: + apiVersion: + description: | + APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: | + Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + spec: + description: | + spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required. + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + volumeSnapshotClassName: + description: | + VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field. + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: | + boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: | + message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information. + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end -}} diff --git a/charts/zfs-localpv/charts/crds/templates/zfsbackup.yaml b/charts/zfs-localpv/charts/crds/templates/zfsbackup.yaml new file mode 100644 index 0000000..b0269d5 --- /dev/null +++ b/charts/zfs-localpv/charts/crds/templates/zfsbackup.yaml @@ -0,0 +1,105 @@ +{{- if .Values.zfsLocalPv.enabled -}} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + {{- include "crds.extraAnnotations" .Values.zfsLocalPv | nindent 4 }} + name: zfsbackups.zfs.openebs.io +spec: + group: zfs.openebs.io + names: + kind: ZFSBackup + listKind: ZFSBackupList + plural: zfsbackups + shortNames: + - zb + singular: zfsbackup + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Previous snapshot for backup + jsonPath: .spec.prevSnapName + name: PrevSnap + type: string + - description: Backup status + jsonPath: .status + name: Status + type: string + - description: Age of the volume + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ZFSBackup describes a zfs backup resource created as a custom + resource + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ZFSBackupSpec is the spec for a ZFSBackup resource + properties: + backupDest: + description: BackupDest is the remote address for backup transfer + minLength: 1 + pattern: ^([0-9]+.[0-9]+.[0-9]+.[0-9]+:[0-9]+)$ + type: string + ownerNodeID: + description: OwnerNodeID is a name of the nodes where the source volume + is + minLength: 1 + type: string + prevSnapName: + description: PrevSnapName is the last completed-backup's snapshot + name + type: string + snapName: + description: SnapName is the snapshot name for backup + minLength: 1 + type: string + volumeName: + description: VolumeName is a name of the volume for which this backup + is destined + minLength: 1 + type: string + required: + - backupDest + - ownerNodeID + - volumeName + type: object + status: + description: ZFSBackupStatus is to hold status of backup + enum: + - Init + - Done + - Failed + - Pending + - InProgress + - Invalid + type: string + required: + - spec + - status + type: object + served: true + storage: true + subresources: {} +{{- end -}} diff --git a/charts/zfs-localpv/charts/crds/templates/zfsnode.yaml b/charts/zfs-localpv/charts/crds/templates/zfsnode.yaml new file mode 100644 index 0000000..2b709ce --- /dev/null +++ b/charts/zfs-localpv/charts/crds/templates/zfsnode.yaml @@ -0,0 +1,86 @@ +{{- if .Values.zfsLocalPv.enabled -}} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + {{- include "crds.extraAnnotations" .Values.zfsLocalPv | nindent 4 }} + name: zfsnodes.zfs.openebs.io +spec: + group: zfs.openebs.io + names: + kind: ZFSNode + listKind: ZFSNodeList + plural: zfsnodes + shortNames: + - zfsnode + singular: zfsnode + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + ZFSNode records information about all zfs pools available + in a node. In general, the openebs node-agent creates the ZFSNode + object & periodically synchronizing the zfs pools available in the node. + ZFSNode has an owner reference pointing to the corresponding node object. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + pools: + items: + description: Pool specifies attributes of a given zfs pool that exists + on the node. + properties: + free: + anyOf: + - type: integer + - type: string + description: Free specifies the available capacity of zfs pool. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + name: + description: Name of the zfs pool. + minLength: 1 + type: string + used: + anyOf: + - type: integer + - type: string + description: Used specifies the used capacity of zfs pool. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + uuid: + description: UUID denotes a unique identity of a zfs pool. + minLength: 1 + type: string + required: + - free + - name + - used + - uuid + type: object + type: array + required: + - pools + type: object + served: true + storage: true +{{- end -}} diff --git a/charts/zfs-localpv/charts/crds/templates/zfsrestore.yaml b/charts/zfs-localpv/charts/crds/templates/zfsrestore.yaml new file mode 100644 index 0000000..40f94b1 --- /dev/null +++ b/charts/zfs-localpv/charts/crds/templates/zfsrestore.yaml @@ -0,0 +1,242 @@ +{{- if .Values.zfsLocalPv.enabled -}} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + {{- include "crds.extraAnnotations" .Values.zfsLocalPv | nindent 4 }} + name: zfsrestores.zfs.openebs.io +spec: + group: zfs.openebs.io + names: + kind: ZFSRestore + listKind: ZFSRestoreList + plural: zfsrestores + singular: zfsrestore + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ZFSRestore describes a cstor restore resource created as a custom + resource + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ZFSRestoreSpec is the spec for a ZFSRestore resource + properties: + ownerNodeID: + description: owner node name where restore volume is present + minLength: 1 + type: string + restoreSrc: + description: it can be ip:port in case of restore from remote or volumeName + in case of local restore + minLength: 1 + pattern: ^([0-9]+.[0-9]+.[0-9]+.[0-9]+:[0-9]+)$ + type: string + volumeName: + description: volume name to where restore has to be performed + minLength: 1 + type: string + required: + - ownerNodeID + - restoreSrc + - volumeName + type: object + status: + description: ZFSRestoreStatus is to hold result of action. + enum: + - Init + - Done + - Failed + - Pending + - InProgress + - Invalid + type: string + volSpec: + description: |- + VolumeInfo defines ZFS volume parameters for all modes in which + ZFS volumes can be created like - ZFS volume with filesystem, + ZFS Volume exposed as zfs or ZFS volume exposed as raw block device. + Some of the parameters can be only set during creation time + (as specified in the details of the parameter), and a few are editable. + In case of Cloned volumes, the parameters are assigned the same values + as the source volume. + properties: + capacity: + description: Capacity of the volume + minLength: 1 + type: string + compression: + description: |- + Compression specifies the block-level compression algorithm to be applied to the ZFS Volume. + The value "on" indicates ZFS to use the default compression algorithm. The default compression + algorithm used by ZFS will be either lzjb or, if the lz4_compress feature is enabled, lz4. + Compression property can be edited after the volume has been created. The change will only + be applied to the newly-written data. For instance, if the Volume was created with "off" and + the next day the compression was modified to "on", the data written prior to setting "on" will + not be compressed. + Default Value: off. + pattern: ^(on|off|lzjb|zstd(?:-fast|-[1-9]|-1[0-9])?|gzip(?:-[1-9])?|zle|lz4)$ + type: string + dedup: + description: |- + Deduplication is the process for removing redundant data at the block level, + reducing the total amount of data stored. If a file system has the dedup property + enabled, duplicate data blocks are removed synchronously. + The result is that only unique data is stored and common components are shared among files. + Deduplication can consume significant processing power (CPU) and memory as well as generate additional disk IO. + Before creating a pool with deduplication enabled, ensure that you have planned your hardware + requirements appropriately and implemented appropriate recovery practices, such as regular backups. + As an alternative to deduplication consider using compression=lz4, as a less resource-intensive alternative. + should be enabled on the zvol. + Dedup property can be edited after the volume has been created. + Default Value: off. + enum: + - "on" + - "off" + type: string + encryption: + description: |- + Enabling the encryption feature allows for the creation of + encrypted filesystems and volumes. ZFS will encrypt file and zvol data, + file attributes, ACLs, permission bits, directory listings, FUID mappings, + and userused / groupused data. ZFS will not encrypt metadata related to the + pool structure, including dataset and snapshot names, dataset hierarchy, + properties, file size, file holes, and deduplication tables + (though the deduplicated data itself is encrypted). + Default Value: off. + pattern: ^(on|off|aes-128-[c,g]cm|aes-192-[c,g]cm|aes-256-[c,g]cm)$ + type: string + fsType: + description: |- + FsType specifies filesystem type for the zfs volume/dataset. + If FsType is provided as "zfs", then the driver will create a + ZFS dataset, formatting is not required as underlying filesystem is ZFS anyway. + If FsType is ext2, ext3, ext4 or xfs, then the driver will create a ZVOL and + format the volume accordingly. + FsType can not be modified once volume has been provisioned. + Default Value: ext4. + type: string + keyformat: + description: |- + KeyFormat specifies format of the encryption key + The supported KeyFormats are passphrase, raw, hex. + enum: + - passphrase + - raw + - hex + type: string + keylocation: + description: KeyLocation is the location of key for the encryption + type: string + ownerNodeID: + description: |- + OwnerNodeID is the Node ID where the ZPOOL is running which is where + the volume has been provisioned. + OwnerNodeID can not be edited after the volume has been provisioned. + minLength: 1 + type: string + poolName: + description: |- + poolName specifies the name of the pool where the volume has been created. + PoolName can not be edited after the volume has been provisioned. + minLength: 1 + type: string + quotaType: + description: |- + quotaType determines whether the dataset volume quota type is of type "quota" or "refquota". + QuotaType can not be modified once volume has been provisioned. + Default Value: quota. + enum: + - quota + - refquota + type: string + recordsize: + description: |- + Specifies a suggested block size for files in the file system. + The size specified must be a power of two greater than or equal to 512 and less than or equal to 128 Kbytes. + RecordSize property can be edited after the volume has been created. + Changing the file system's recordsize affects only files created afterward; existing files are unaffected. + Default Value: 128k. + minLength: 1 + type: string + shared: + description: |- + Shared specifies whether the volume can be shared among multiple pods. + If it is not set to "yes", then the ZFS-LocalPV Driver will not allow + the volumes to be mounted by more than one pods. + enum: + - "yes" + - "no" + type: string + snapname: + description: |- + SnapName specifies the name of the snapshot where the volume has been cloned from. + Snapname can not be edited after the volume has been provisioned. + type: string + thinProvision: + description: |- + ThinProvision describes whether space reservation for the source volume is required or not. + The value "yes" indicates that volume should be thin provisioned and "no" means thick provisioning of the volume. + If thinProvision is set to "yes" then volume can be provisioned even if the ZPOOL does not + have the enough capacity. + If thinProvision is set to "no" then volume can be provisioned only if the ZPOOL has enough + capacity and capacity required by volume can be reserved. + ThinProvision can not be modified once volume has been provisioned. + Default Value: no. + enum: + - "yes" + - "no" + type: string + volblocksize: + description: |- + VolBlockSize specifies the block size for the zvol. + The volsize can only be set to a multiple of volblocksize, and cannot be zero. + VolBlockSize can not be edited after the volume has been provisioned. + Default Value: 8k. + minLength: 1 + type: string + volumeType: + description: |- + volumeType determines whether the volume is of type "DATASET" or "ZVOL". + If fstype provided in the storageclass is "zfs", a volume of type dataset will be created. + If "ext4", "ext3", "ext2" or "xfs" is mentioned as fstype + in the storageclass, then a volume of type zvol will be created, which will be + further formatted as the fstype provided in the storageclass. + VolumeType can not be modified once volume has been provisioned. + enum: + - ZVOL + - DATASET + type: string + required: + - capacity + - ownerNodeID + - poolName + - volumeType + type: object + required: + - spec + - status + type: object + served: true + storage: true +{{- end -}} diff --git a/charts/zfs-localpv/charts/crds/templates/zfssnapshot.yaml b/charts/zfs-localpv/charts/crds/templates/zfssnapshot.yaml new file mode 100644 index 0000000..f87c60d --- /dev/null +++ b/charts/zfs-localpv/charts/crds/templates/zfssnapshot.yaml @@ -0,0 +1,397 @@ +{{- if .Values.zfsLocalPv.enabled -}} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + {{- include "crds.extraAnnotations" .Values.zfsLocalPv | nindent 4 }} + name: zfssnapshots.zfs.openebs.io +spec: + group: zfs.openebs.io + names: + kind: ZFSSnapshot + listKind: ZFSSnapshotList + plural: zfssnapshots + shortNames: + - zfssnap + singular: zfssnapshot + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ZFSSnapshot represents a ZFS Snapshot of the zfsvolume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + VolumeInfo defines ZFS volume parameters for all modes in which + ZFS volumes can be created like - ZFS volume with filesystem, + ZFS Volume exposed as zfs or ZFS volume exposed as raw block device. + Some of the parameters can be only set during creation time + (as specified in the details of the parameter), and a few are editable. + In case of Cloned volumes, the parameters are assigned the same values + as the source volume. + properties: + capacity: + description: Capacity of the volume + minLength: 1 + type: string + compression: + description: |- + Compression specifies the block-level compression algorithm to be applied to the ZFS Volume. + The value "on" indicates ZFS to use the default compression algorithm. The default compression + algorithm used by ZFS will be either lzjb or, if the lz4_compress feature is enabled, lz4. + Compression property can be edited after the volume has been created. The change will only + be applied to the newly-written data. For instance, if the Volume was created with "off" and + the next day the compression was modified to "on", the data written prior to setting "on" will + not be compressed. + Default Value: off. + pattern: ^(on|off|lzjb|zstd(?:-fast|-[1-9]|-1[0-9])?|gzip(?:-[1-9])?|zle|lz4)$ + type: string + dedup: + description: |- + Deduplication is the process for removing redundant data at the block level, + reducing the total amount of data stored. If a file system has the dedup property + enabled, duplicate data blocks are removed synchronously. + The result is that only unique data is stored and common components are shared among files. + Deduplication can consume significant processing power (CPU) and memory as well as generate additional disk IO. + Before creating a pool with deduplication enabled, ensure that you have planned your hardware + requirements appropriately and implemented appropriate recovery practices, such as regular backups. + As an alternative to deduplication consider using compression=lz4, as a less resource-intensive alternative. + should be enabled on the zvol. + Dedup property can be edited after the volume has been created. + Default Value: off. + enum: + - "on" + - "off" + type: string + encryption: + description: |- + Enabling the encryption feature allows for the creation of + encrypted filesystems and volumes. ZFS will encrypt file and zvol data, + file attributes, ACLs, permission bits, directory listings, FUID mappings, + and userused / groupused data. ZFS will not encrypt metadata related to the + pool structure, including dataset and snapshot names, dataset hierarchy, + properties, file size, file holes, and deduplication tables + (though the deduplicated data itself is encrypted). + Default Value: off. + pattern: ^(on|off|aes-128-[c,g]cm|aes-192-[c,g]cm|aes-256-[c,g]cm)$ + type: string + fsType: + description: |- + FsType specifies filesystem type for the zfs volume/dataset. + If FsType is provided as "zfs", then the driver will create a + ZFS dataset, formatting is not required as underlying filesystem is ZFS anyway. + If FsType is ext2, ext3, ext4 or xfs, then the driver will create a ZVOL and + format the volume accordingly. + FsType can not be modified once volume has been provisioned. + Default Value: ext4. + type: string + keyformat: + description: |- + KeyFormat specifies format of the encryption key + The supported KeyFormats are passphrase, raw, hex. + enum: + - passphrase + - raw + - hex + type: string + keylocation: + description: KeyLocation is the location of key for the encryption + type: string + ownerNodeID: + description: |- + OwnerNodeID is the Node ID where the ZPOOL is running which is where + the volume has been provisioned. + OwnerNodeID can not be edited after the volume has been provisioned. + minLength: 1 + type: string + poolName: + description: |- + poolName specifies the name of the pool where the volume has been created. + PoolName can not be edited after the volume has been provisioned. + minLength: 1 + type: string + quotaType: + description: |- + quotaType determines whether the dataset volume quota type is of type "quota" or "refquota". + QuotaType can not be modified once volume has been provisioned. + Default Value: quota. + enum: + - quota + - refquota + type: string + recordsize: + description: |- + Specifies a suggested block size for files in the file system. + The size specified must be a power of two greater than or equal to 512 and less than or equal to 128 Kbytes. + RecordSize property can be edited after the volume has been created. + Changing the file system's recordsize affects only files created afterward; existing files are unaffected. + Default Value: 128k. + minLength: 1 + type: string + shared: + description: |- + Shared specifies whether the volume can be shared among multiple pods. + If it is not set to "yes", then the ZFS-LocalPV Driver will not allow + the volumes to be mounted by more than one pods. + enum: + - "yes" + - "no" + type: string + snapname: + description: |- + SnapName specifies the name of the snapshot where the volume has been cloned from. + Snapname can not be edited after the volume has been provisioned. + type: string + thinProvision: + description: |- + ThinProvision describes whether space reservation for the source volume is required or not. + The value "yes" indicates that volume should be thin provisioned and "no" means thick provisioning of the volume. + If thinProvision is set to "yes" then volume can be provisioned even if the ZPOOL does not + have the enough capacity. + If thinProvision is set to "no" then volume can be provisioned only if the ZPOOL has enough + capacity and capacity required by volume can be reserved. + ThinProvision can not be modified once volume has been provisioned. + Default Value: no. + enum: + - "yes" + - "no" + type: string + volblocksize: + description: |- + VolBlockSize specifies the block size for the zvol. + The volsize can only be set to a multiple of volblocksize, and cannot be zero. + VolBlockSize can not be edited after the volume has been provisioned. + Default Value: 8k. + minLength: 1 + type: string + volumeType: + description: |- + volumeType determines whether the volume is of type "DATASET" or "ZVOL". + If fstype provided in the storageclass is "zfs", a volume of type dataset will be created. + If "ext4", "ext3", "ext2" or "xfs" is mentioned as fstype + in the storageclass, then a volume of type zvol will be created, which will be + further formatted as the fstype provided in the storageclass. + VolumeType can not be modified once volume has been provisioned. + enum: + - ZVOL + - DATASET + type: string + required: + - capacity + - ownerNodeID + - poolName + - volumeType + type: object + status: + description: SnapStatus string that reflects if the snapshot was created + successfully + properties: + state: + type: string + type: object + required: + - spec + - status + type: object + served: true + storage: true + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ZFSSnapshot represents a ZFS Snapshot of the zfsvolume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + VolumeInfo defines ZFS volume parameters for all modes in which + ZFS volumes can be created like - ZFS volume with filesystem, + ZFS Volume exposed as zfs or ZFS volume exposed as raw block device. + Some of the parameters can be only set during creation time + (as specified in the details of the parameter), and a few are editable. + In case of Cloned volumes, the parameters are assigned the same values + as the source volume. + properties: + capacity: + description: Capacity of the volume + minLength: 1 + type: string + compression: + description: |- + Compression specifies the block-level compression algorithm to be applied to the ZFS Volume. + The value "on" indicates ZFS to use the default compression algorithm. The default compression + algorithm used by ZFS will be either lzjb or, if the lz4_compress feature is enabled, lz4. + Compression property can be edited after the volume has been created. The change will only + be applied to the newly-written data. For instance, if the Volume was created with "off" and + the next day the compression was modified to "on", the data written prior to setting "on" will + not be compressed. + Default Value: off. + pattern: ^(on|off|lzjb|gzip|gzip-[1-9]|zle|lz4)$ + type: string + dedup: + description: |- + Deduplication is the process for removing redundant data at the block level, + reducing the total amount of data stored. If a file system has the dedup property + enabled, duplicate data blocks are removed synchronously. + The result is that only unique data is stored and common components are shared among files. + Deduplication can consume significant processing power (CPU) and memory as well as generate additional disk IO. + Before creating a pool with deduplication enabled, ensure that you have planned your hardware + requirements appropriately and implemented appropriate recovery practices, such as regular backups. + As an alternative to deduplication consider using compression=lz4, as a less resource-intensive alternative. + should be enabled on the zvol. + Dedup property can be edited after the volume has been created. + Default Value: off. + enum: + - "on" + - "off" + type: string + encryption: + description: |- + Enabling the encryption feature allows for the creation of + encrypted filesystems and volumes. ZFS will encrypt file and zvol data, + file attributes, ACLs, permission bits, directory listings, FUID mappings, + and userused / groupused data. ZFS will not encrypt metadata related to the + pool structure, including dataset and snapshot names, dataset hierarchy, + properties, file size, file holes, and deduplication tables + (though the deduplicated data itself is encrypted). + Default Value: off. + pattern: ^(on|off|aes-128-[c,g]cm|aes-192-[c,g]cm|aes-256-[c,g]cm)$ + type: string + fsType: + description: |- + FsType specifies filesystem type for the zfs volume/dataset. + If FsType is provided as "zfs", then the driver will create a + ZFS dataset, formatting is not required as underlying filesystem is ZFS anyway. + If FsType is ext2, ext3, ext4 or xfs, then the driver will create a ZVOL and + format the volume accordingly. + FsType can not be modified once volume has been provisioned. + Default Value: ext4. + type: string + keyformat: + description: |- + KeyFormat specifies format of the encryption key + The supported KeyFormats are passphrase, raw, hex. + enum: + - passphrase + - raw + - hex + type: string + keylocation: + description: KeyLocation is the location of key for the encryption + type: string + ownerNodeID: + description: |- + OwnerNodeID is the Node ID where the ZPOOL is running which is where + the volume has been provisioned. + OwnerNodeID can not be edited after the volume has been provisioned. + minLength: 1 + type: string + poolName: + description: |- + poolName specifies the name of the pool where the volume has been created. + PoolName can not be edited after the volume has been provisioned. + minLength: 1 + type: string + recordsize: + description: |- + Specifies a suggested block size for files in the file system. + The size specified must be a power of two greater than or equal to 512 and less than or equal to 128 Kbytes. + RecordSize property can be edited after the volume has been created. + Changing the file system's recordsize affects only files created afterward; existing files are unaffected. + Default Value: 128k. + minLength: 1 + type: string + snapname: + description: |- + SnapName specifies the name of the snapshot where the volume has been cloned from. + Snapname can not be edited after the volume has been provisioned. + type: string + thinProvision: + description: |- + ThinProvision describes whether space reservation for the source volume is required or not. + The value "yes" indicates that volume should be thin provisioned and "no" means thick provisioning of the volume. + If thinProvision is set to "yes" then volume can be provisioned even if the ZPOOL does not + have the enough capacity. + If thinProvision is set to "no" then volume can be provisioned only if the ZPOOL has enough + capacity and capacity required by volume can be reserved. + ThinProvision can not be modified once volume has been provisioned. + Default Value: no. + enum: + - "yes" + - "no" + type: string + volblocksize: + description: |- + VolBlockSize specifies the block size for the zvol. + The volsize can only be set to a multiple of volblocksize, and cannot be zero. + VolBlockSize can not be edited after the volume has been provisioned. + Default Value: 8k. + minLength: 1 + type: string + volumeType: + description: |- + volumeType determines whether the volume is of type "DATASET" or "ZVOL". + If fstype provided in the storageclass is "zfs", a volume of type dataset will be created. + If "ext4", "ext3", "ext2" or "xfs" is mentioned as fstype + in the storageclass, then a volume of type zvol will be created, which will be + further formatted as the fstype provided in the storageclass. + VolumeType can not be modified once volume has been provisioned. + enum: + - ZVOL + - DATASET + type: string + required: + - capacity + - ownerNodeID + - poolName + - volumeType + type: object + status: + description: SnapStatus string that reflects if the snapshot was created + successfully + properties: + state: + type: string + type: object + required: + - spec + - status + type: object + served: true + storage: false +{{- end -}} diff --git a/charts/zfs-localpv/charts/crds/templates/zfsvolume.yaml b/charts/zfs-localpv/charts/crds/templates/zfsvolume.yaml new file mode 100644 index 0000000..adbd859 --- /dev/null +++ b/charts/zfs-localpv/charts/crds/templates/zfsvolume.yaml @@ -0,0 +1,465 @@ +{{- if .Values.zfsLocalPv.enabled -}} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + {{- include "crds.extraAnnotations" .Values.zfsLocalPv | nindent 4 }} + name: zfsvolumes.zfs.openebs.io +spec: + group: zfs.openebs.io + names: + kind: ZFSVolume + listKind: ZFSVolumeList + plural: zfsvolumes + shortNames: + - zfsvol + - zv + singular: zfsvolume + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: ZFS Pool where the volume is created + jsonPath: .spec.poolName + name: ZPool + type: string + - description: Node where the volume is created + jsonPath: .spec.ownerNodeID + name: NodeID + type: string + - description: Size of the volume + jsonPath: .spec.capacity + name: Size + type: string + - description: Status of the volume + jsonPath: .status.state + name: Status + type: string + - description: filesystem created on the volume + jsonPath: .spec.fsType + name: Filesystem + type: string + - description: Age of the volume + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ZFSVolume represents a ZFS based volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + VolumeInfo defines ZFS volume parameters for all modes in which + ZFS volumes can be created like - ZFS volume with filesystem, + ZFS Volume exposed as zfs or ZFS volume exposed as raw block device. + Some of the parameters can be only set during creation time + (as specified in the details of the parameter), and a few are editable. + In case of Cloned volumes, the parameters are assigned the same values + as the source volume. + properties: + capacity: + description: Capacity of the volume + minLength: 1 + type: string + compression: + description: |- + Compression specifies the block-level compression algorithm to be applied to the ZFS Volume. + The value "on" indicates ZFS to use the default compression algorithm. The default compression + algorithm used by ZFS will be either lzjb or, if the lz4_compress feature is enabled, lz4. + Compression property can be edited after the volume has been created. The change will only + be applied to the newly-written data. For instance, if the Volume was created with "off" and + the next day the compression was modified to "on", the data written prior to setting "on" will + not be compressed. + Default Value: off. + pattern: ^(on|off|lzjb|zstd(?:-fast|-[1-9]|-1[0-9])?|gzip(?:-[1-9])?|zle|lz4)$ + type: string + dedup: + description: |- + Deduplication is the process for removing redundant data at the block level, + reducing the total amount of data stored. If a file system has the dedup property + enabled, duplicate data blocks are removed synchronously. + The result is that only unique data is stored and common components are shared among files. + Deduplication can consume significant processing power (CPU) and memory as well as generate additional disk IO. + Before creating a pool with deduplication enabled, ensure that you have planned your hardware + requirements appropriately and implemented appropriate recovery practices, such as regular backups. + As an alternative to deduplication consider using compression=lz4, as a less resource-intensive alternative. + should be enabled on the zvol. + Dedup property can be edited after the volume has been created. + Default Value: off. + enum: + - "on" + - "off" + type: string + encryption: + description: |- + Enabling the encryption feature allows for the creation of + encrypted filesystems and volumes. ZFS will encrypt file and zvol data, + file attributes, ACLs, permission bits, directory listings, FUID mappings, + and userused / groupused data. ZFS will not encrypt metadata related to the + pool structure, including dataset and snapshot names, dataset hierarchy, + properties, file size, file holes, and deduplication tables + (though the deduplicated data itself is encrypted). + Default Value: off. + pattern: ^(on|off|aes-128-[c,g]cm|aes-192-[c,g]cm|aes-256-[c,g]cm)$ + type: string + fsType: + description: |- + FsType specifies filesystem type for the zfs volume/dataset. + If FsType is provided as "zfs", then the driver will create a + ZFS dataset, formatting is not required as underlying filesystem is ZFS anyway. + If FsType is ext2, ext3, ext4 or xfs, then the driver will create a ZVOL and + format the volume accordingly. + FsType can not be modified once volume has been provisioned. + Default Value: ext4. + type: string + keyformat: + description: |- + KeyFormat specifies format of the encryption key + The supported KeyFormats are passphrase, raw, hex. + enum: + - passphrase + - raw + - hex + type: string + keylocation: + description: KeyLocation is the location of key for the encryption + type: string + ownerNodeID: + description: |- + OwnerNodeID is the Node ID where the ZPOOL is running which is where + the volume has been provisioned. + OwnerNodeID can not be edited after the volume has been provisioned. + minLength: 1 + type: string + poolName: + description: |- + poolName specifies the name of the pool where the volume has been created. + PoolName can not be edited after the volume has been provisioned. + minLength: 1 + type: string + quotaType: + description: |- + quotaType determines whether the dataset volume quota type is of type "quota" or "refquota". + QuotaType can not be modified once volume has been provisioned. + Default Value: quota. + enum: + - quota + - refquota + type: string + recordsize: + description: |- + Specifies a suggested block size for files in the file system. + The size specified must be a power of two greater than or equal to 512 and less than or equal to 128 Kbytes. + RecordSize property can be edited after the volume has been created. + Changing the file system's recordsize affects only files created afterward; existing files are unaffected. + Default Value: 128k. + minLength: 1 + type: string + shared: + description: |- + Shared specifies whether the volume can be shared among multiple pods. + If it is not set to "yes", then the ZFS-LocalPV Driver will not allow + the volumes to be mounted by more than one pods. + enum: + - "yes" + - "no" + type: string + snapname: + description: |- + SnapName specifies the name of the snapshot where the volume has been cloned from. + Snapname can not be edited after the volume has been provisioned. + type: string + thinProvision: + description: |- + ThinProvision describes whether space reservation for the source volume is required or not. + The value "yes" indicates that volume should be thin provisioned and "no" means thick provisioning of the volume. + If thinProvision is set to "yes" then volume can be provisioned even if the ZPOOL does not + have the enough capacity. + If thinProvision is set to "no" then volume can be provisioned only if the ZPOOL has enough + capacity and capacity required by volume can be reserved. + ThinProvision can not be modified once volume has been provisioned. + Default Value: no. + enum: + - "yes" + - "no" + type: string + volblocksize: + description: |- + VolBlockSize specifies the block size for the zvol. + The volsize can only be set to a multiple of volblocksize, and cannot be zero. + VolBlockSize can not be edited after the volume has been provisioned. + Default Value: 8k. + minLength: 1 + type: string + volumeType: + description: |- + volumeType determines whether the volume is of type "DATASET" or "ZVOL". + If fstype provided in the storageclass is "zfs", a volume of type dataset will be created. + If "ext4", "ext3", "ext2" or "xfs" is mentioned as fstype + in the storageclass, then a volume of type zvol will be created, which will be + further formatted as the fstype provided in the storageclass. + VolumeType can not be modified once volume has been provisioned. + enum: + - ZVOL + - DATASET + type: string + required: + - capacity + - ownerNodeID + - poolName + - volumeType + type: object + status: + description: VolStatus string that specifies the current state of the + volume provisioning request. + properties: + state: + description: |- + State specifies the current state of the volume provisioning request. + The state "Pending" means that the volume creation request has not + processed yet. The state "Ready" means that the volume has been created + and it is ready for the use. + enum: + - Pending + - Ready + - Failed + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - description: ZFS Pool where the volume is created + jsonPath: .spec.poolName + name: ZPool + type: string + - description: Node where the volume is created + jsonPath: .spec.ownerNodeID + name: Node + type: string + - description: Size of the volume + jsonPath: .spec.capacity + name: Size + type: string + - description: Status of the volume + jsonPath: .status.state + name: Status + type: string + - description: filesystem created on the volume + jsonPath: .spec.fsType + name: Filesystem + type: string + - description: Age of the volume + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ZFSVolume represents a ZFS based volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + VolumeInfo defines ZFS volume parameters for all modes in which + ZFS volumes can be created like - ZFS volume with filesystem, + ZFS Volume exposed as zfs or ZFS volume exposed as raw block device. + Some of the parameters can be only set during creation time + (as specified in the details of the parameter), and a few are editable. + In case of Cloned volumes, the parameters are assigned the same values + as the source volume. + properties: + capacity: + description: Capacity of the volume + minLength: 1 + type: string + compression: + description: |- + Compression specifies the block-level compression algorithm to be applied to the ZFS Volume. + The value "on" indicates ZFS to use the default compression algorithm. The default compression + algorithm used by ZFS will be either lzjb or, if the lz4_compress feature is enabled, lz4. + Compression property can be edited after the volume has been created. The change will only + be applied to the newly-written data. For instance, if the Volume was created with "off" and + the next day the compression was modified to "on", the data written prior to setting "on" will + not be compressed. + Default Value: off. + pattern: ^(on|off|lzjb|gzip|gzip-[1-9]|zle|lz4)$ + type: string + dedup: + description: |- + Deduplication is the process for removing redundant data at the block level, + reducing the total amount of data stored. If a file system has the dedup property + enabled, duplicate data blocks are removed synchronously. + The result is that only unique data is stored and common components are shared among files. + Deduplication can consume significant processing power (CPU) and memory as well as generate additional disk IO. + Before creating a pool with deduplication enabled, ensure that you have planned your hardware + requirements appropriately and implemented appropriate recovery practices, such as regular backups. + As an alternative to deduplication consider using compression=lz4, as a less resource-intensive alternative. + should be enabled on the zvol. + Dedup property can be edited after the volume has been created. + Default Value: off. + enum: + - "on" + - "off" + type: string + encryption: + description: |- + Enabling the encryption feature allows for the creation of + encrypted filesystems and volumes. ZFS will encrypt file and zvol data, + file attributes, ACLs, permission bits, directory listings, FUID mappings, + and userused / groupused data. ZFS will not encrypt metadata related to the + pool structure, including dataset and snapshot names, dataset hierarchy, + properties, file size, file holes, and deduplication tables + (though the deduplicated data itself is encrypted). + Default Value: off. + pattern: ^(on|off|aes-128-[c,g]cm|aes-192-[c,g]cm|aes-256-[c,g]cm)$ + type: string + fsType: + description: |- + FsType specifies filesystem type for the zfs volume/dataset. + If FsType is provided as "zfs", then the driver will create a + ZFS dataset, formatting is not required as underlying filesystem is ZFS anyway. + If FsType is ext2, ext3, ext4 or xfs, then the driver will create a ZVOL and + format the volume accordingly. + FsType can not be modified once volume has been provisioned. + Default Value: ext4. + type: string + keyformat: + description: |- + KeyFormat specifies format of the encryption key + The supported KeyFormats are passphrase, raw, hex. + enum: + - passphrase + - raw + - hex + type: string + keylocation: + description: KeyLocation is the location of key for the encryption + type: string + ownerNodeID: + description: |- + OwnerNodeID is the Node ID where the ZPOOL is running which is where + the volume has been provisioned. + OwnerNodeID can not be edited after the volume has been provisioned. + minLength: 1 + type: string + poolName: + description: |- + poolName specifies the name of the pool where the volume has been created. + PoolName can not be edited after the volume has been provisioned. + minLength: 1 + type: string + recordsize: + description: |- + Specifies a suggested block size for files in the file system. + The size specified must be a power of two greater than or equal to 512 and less than or equal to 128 Kbytes. + RecordSize property can be edited after the volume has been created. + Changing the file system's recordsize affects only files created afterward; existing files are unaffected. + Default Value: 128k. + minLength: 1 + type: string + snapname: + description: |- + SnapName specifies the name of the snapshot where the volume has been cloned from. + Snapname can not be edited after the volume has been provisioned. + type: string + thinProvision: + description: |- + ThinProvision describes whether space reservation for the source volume is required or not. + The value "yes" indicates that volume should be thin provisioned and "no" means thick provisioning of the volume. + If thinProvision is set to "yes" then volume can be provisioned even if the ZPOOL does not + have the enough capacity. + If thinProvision is set to "no" then volume can be provisioned only if the ZPOOL has enough + capacity and capacity required by volume can be reserved. + ThinProvision can not be modified once volume has been provisioned. + Default Value: no. + enum: + - "yes" + - "no" + type: string + volblocksize: + description: |- + VolBlockSize specifies the block size for the zvol. + The volsize can only be set to a multiple of volblocksize, and cannot be zero. + VolBlockSize can not be edited after the volume has been provisioned. + Default Value: 8k. + minLength: 1 + type: string + volumeType: + description: |- + volumeType determines whether the volume is of type "DATASET" or "ZVOL". + If fstype provided in the storageclass is "zfs", a volume of type dataset will be created. + If "ext4", "ext3", "ext2" or "xfs" is mentioned as fstype + in the storageclass, then a volume of type zvol will be created, which will be + further formatted as the fstype provided in the storageclass. + VolumeType can not be modified once volume has been provisioned. + enum: + - ZVOL + - DATASET + type: string + required: + - capacity + - ownerNodeID + - poolName + - volumeType + type: object + status: + description: VolStatus string that specifies the current state of the + volume provisioning request. + properties: + state: + description: |- + State specifies the current state of the volume provisioning request. + The state "Pending" means that the volume creation request has not + processed yet. The state "Ready" means that the volume has been created + and it is ready for the use. + enum: + - Pending + - Ready + type: string + type: object + required: + - spec + type: object + served: true + storage: false + subresources: {} +{{- end -}} diff --git a/charts/zfs-localpv/charts/crds/values.yaml b/charts/zfs-localpv/charts/crds/values.yaml new file mode 100644 index 0000000..8ebde58 --- /dev/null +++ b/charts/zfs-localpv/charts/crds/values.yaml @@ -0,0 +1,12 @@ +zfsLocalPv: + # Install zfs-localpv CRDs + enabled: true + # -- Keep CRDs on chart uninstall + keep: true + +csi: + volumeSnapshots: + # Install Volume Snapshot CRDs + enabled: true + # -- Keep CRDs on chart uninstall + keep: true diff --git a/charts/zfs-localpv/templates/NOTES.txt b/charts/zfs-localpv/templates/NOTES.txt new file mode 100644 index 0000000..c0454bc --- /dev/null +++ b/charts/zfs-localpv/templates/NOTES.txt @@ -0,0 +1,5 @@ +The OpenEBS ZFS LocalPV has been installed. Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} -l role=openebs-zfs + +For more information, visit our Slack at https://openebs.io/community or view +the documentation online at http://docs.openebs.io/. diff --git a/charts/zfs-localpv/templates/_helpers.tpl b/charts/zfs-localpv/templates/_helpers.tpl new file mode 100644 index 0000000..834f141 --- /dev/null +++ b/charts/zfs-localpv/templates/_helpers.tpl @@ -0,0 +1,162 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "zfslocalpv.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified localpv provisioner 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 "zfslocalpv.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "zfslocalpv.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Create the name of the service account for controller +*/}} +{{- define "zfslocalpv.zfsController.serviceAccountName" -}} +{{- if .Values.serviceAccount.zfsController.create }} +{{- default (include "zfslocalpv.fullname" .) .Values.serviceAccount.zfsController.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.zfsController.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "zfslocalpv.zfsNode.serviceAccountName" -}} +{{- if .Values.serviceAccount.zfsNode.create }} +{{- default (include "zfslocalpv.fullname" .) .Values.serviceAccount.zfsNode.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.zfsNode.name }} +{{- end -}} +{{- end -}} + +{{/* +Define meta labels for openebs zfs-localpv components +*/}} +{{- define "zfslocalpv.common.metaLabels" -}} +{{- if or (not (hasKey .Values "enableHelmMetaLabels")) .Values.enableHelmMetaLabels -}} +chart: {{ template "zfslocalpv.chart" . }} +heritage: {{ .Release.Service }} +{{ end -}} +openebs.io/version: {{ .Chart.AppVersion | quote }} +role: {{ .Values.role | quote }} +{{- end -}} + +{{/* +Create match labels for openebs zfs-localpv controller +*/}} +{{- define "zfslocalpv.zfsController.matchLabels" -}} +app: {{ .Values.zfsController.componentName | quote }} +{{ if or (not (hasKey .Values "enableHelmMetaLabels")) .Values.enableHelmMetaLabels -}} +release: {{ .Release.Name }} +{{ end -}} +component: {{ .Values.zfsController.componentName | quote }} +{{- end -}} + +{{/* +Create component labels for zfslocalpv controller +*/}} +{{- define "zfslocalpv.zfsController.componentLabels" -}} +openebs.io/component-name: {{ .Values.zfsController.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for openebs zfs-localpv controller +*/}} +{{- define "zfslocalpv.zfsController.labels" -}} +{{ include "zfslocalpv.common.metaLabels" . }} +{{ include "zfslocalpv.zfsController.matchLabels" . }} +{{ include "zfslocalpv.zfsController.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for openebs zfs-localpv node daemon +*/}} +{{- define "zfslocalpv.zfsNode.matchLabels" -}} +name: {{ .Values.zfsNode.componentName | quote }}{{ if or (not (hasKey .Values "enableHelmMetaLabels")) .Values.enableHelmMetaLabels }} +release: {{ .Release.Name }} +{{- end -}} +{{- end -}} + +{{/* +Create component labels openebs zfs-localpv node daemon +*/}} +{{- define "zfslocalpv.zfsNode.componentLabels" -}} +app: {{ .Values.zfsNode.componentName | quote }} +openebs.io/component-name: {{ .Values.zfsNode.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for openebs zfs-localpv node daemon +*/}} +{{- define "zfslocalpv.zfsNode.labels" -}} +{{ include "zfslocalpv.common.metaLabels" . }} +{{ include "zfslocalpv.zfsNode.matchLabels" . }} +{{ include "zfslocalpv.zfsNode.componentLabels" . }} +{{- end -}} + +{{/* +Create the name of the priority class for csi node plugin +*/}} +{{- define "zfslocalpv.zfsNode.priorityClassName" -}} +{{- if .Values.zfsNode.priorityClass.create }} +{{- printf "%s-%s" .Release.Name .Values.zfsNode.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Values.zfsNode.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Create the name of the priority class for csi controller plugin +*/}} +{{- define "zfslocalpv.zfsController.priorityClassName" -}} +{{- if .Values.zfsController.priorityClass.create }} +{{- printf "%s-%s" .Release.Name .Values.zfsController.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Values.zfsController.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Enable zfsController containers leader election if replicas > 1 +*/}} +{{- define "zfslocalpv.zfsController.leaderElection" -}} +{{- with .Values.zfsController.replicas | int }} +{{- if gt . 1 }} +- "--leader-election" +{{- end }} +{{- end }} +{{- end }} + +{{/* +Ensure that the path to kubelet ends with a slash +*/}} +{{- define "zfslocalpv.zfsNode.kubeletDir" -}} +{{- printf "%s/" (.Values.zfsNode.kubeletDir | trimSuffix "/") -}} +{{- end }} diff --git a/charts/zfs-localpv/templates/configmap.yaml b/charts/zfs-localpv/templates/configmap.yaml new file mode 100644 index 0000000..5f1b334 --- /dev/null +++ b/charts/zfs-localpv/templates/configmap.yaml @@ -0,0 +1,17 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: openebs-zfspv-bin + namespace: {{ .Release.Namespace }} # should be the same namespace where it is getting mounted + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +data: + zfs: | + #!/bin/sh + if [ -x /host/sbin/zfs ]; then + chroot /host /sbin/zfs "$@" + elif [ -x /host/usr/sbin/zfs ]; then + chroot /host /usr/sbin/zfs "$@" + else + chroot /host "{{ .Values.zfs.bin }}" "$@" + fi diff --git a/charts/zfs-localpv/templates/csidriver.yaml b/charts/zfs-localpv/templates/csidriver.yaml new file mode 100644 index 0000000..c14b146 --- /dev/null +++ b/charts/zfs-localpv/templates/csidriver.yaml @@ -0,0 +1,10 @@ +# Create the CSI Driver object +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: zfs.csi.openebs.io +spec: + # do not require volumeattachment + attachRequired: false + podInfoOnMount: false + storageCapacity: {{ .Values.feature.storageCapacity }} diff --git a/charts/zfs-localpv/templates/priority-class.yaml b/charts/zfs-localpv/templates/priority-class.yaml new file mode 100644 index 0000000..71ad435 --- /dev/null +++ b/charts/zfs-localpv/templates/priority-class.yaml @@ -0,0 +1,19 @@ +{{- if .Values.zfsController.priorityClass.create }} +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ template "zfslocalpv.zfsController.priorityClassName" . }} +value: 900000000 +globalDefault: false +description: "This priority class should be used for the CStor CSI driver controller deployment only." +{{- end }} +--- +{{- if .Values.zfsNode.priorityClass.create }} +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ template "zfslocalpv.zfsNode.priorityClassName" . }} +value: 900001000 +globalDefault: false +description: "This priority class should be used for the CStor CSI driver node deployment only." +{{- end }} diff --git a/charts/zfs-localpv/templates/psp.yaml b/charts/zfs-localpv/templates/psp.yaml new file mode 100644 index 0000000..33be4dc --- /dev/null +++ b/charts/zfs-localpv/templates/psp.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: openebs-zfs-node-psp + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +spec: + privileged: true + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: true + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/charts/zfs-localpv/templates/rbac.yaml b/charts/zfs-localpv/templates/rbac.yaml new file mode 100644 index 0000000..66a9931 --- /dev/null +++ b/charts/zfs-localpv/templates/rbac.yaml @@ -0,0 +1,200 @@ +{{- if .Values.serviceAccount.zfsController.create -}} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ .Values.serviceAccount.zfsController.name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 4 }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-provisioner-role + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["*"] + - apiGroups: [""] + resources: ["persistentvolumes", "services"] + verbs: ["get", "list", "watch", "create", "delete", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses", "csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [ "storage.k8s.io" ] + resources: [ "csistoragecapacities"] + verbs: ["*"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["*"] + resources: ["zfsvolumes", "zfssnapshots", "zfsbackups", "zfsrestores", "zfsnodes"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-provisioner-binding + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.zfsController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-zfs-provisioner-role + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-snapshotter-role + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "list", "watch", "delete"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-snapshotter-binding + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.zfsController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-zfs-snapshotter-role + apiGroup: rbac.authorization.k8s.io +--- +{{ end }} +{{- if .Values.serviceAccount.zfsNode.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.zfsNode.name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-driver-registrar-role + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumes", "nodes", "services"] + verbs: ["get", "list"] + - apiGroups: ["*"] + resources: ["zfsvolumes", "zfssnapshots", "zfsbackups", "zfsrestores", "zfsnodes"] + verbs: ["get", "list", "watch", "create", "update", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-driver-registrar-binding + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.zfsNode.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-zfs-driver-registrar-role + apiGroup: rbac.authorization.k8s.io + +{{- if .Values.rbac.pspEnabled }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-node-role + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - openebs-zfs-node-psp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: openebs-zfs-node-binding + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openebs-zfs-node-role +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.zfsNode.name }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/charts/zfs-localpv/templates/zfs-controller.yaml b/charts/zfs-localpv/templates/zfs-controller.yaml new file mode 100644 index 0000000..f017cc0 --- /dev/null +++ b/charts/zfs-localpv/templates/zfs-controller.yaml @@ -0,0 +1,177 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "zfslocalpv.fullname" . }}-controller + namespace: {{ .Release.Namespace }} + {{- with .Values.zfsController.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "zfslocalpv.zfsController.matchLabels" . | nindent 6 }} + replicas: {{ .Values.zfsController.replicas }} + template: + metadata: + {{- with .Values.zfsController.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 8 -}} + {{- with .Values.zfsController.podLabels}} + {{ toYaml . | nindent 8 -}} + {{- end}} + {{- with .Values.loggingLabels}} + {{ toYaml . | nindent 8 -}} + {{- end}} + spec: +{{- if .Values.zfsController.priorityClass.create }} + priorityClassName: {{ template "zfslocalpv.zfsController.priorityClassName" . }} +{{- end }} + serviceAccountName: {{ .Values.serviceAccount.zfsController.name }} +{{- if .Values.zfsController.initContainers }} + initContainers: +{{- range $key, $value := .Values.zfsController.initContainers }} + - name: {{ $key }} +{{ toYaml $value | indent 10 }} +{{- end }} +{{- end }} + containers: + - name: {{ .Values.zfsController.resizer.name }} + image: "{{ .Values.zfsController.resizer.image.registry }}{{ .Values.zfsController.resizer.image.repository }}:{{ .Values.zfsController.resizer.image.tag }}" + args: + - "--v=5" + - "--csi-address=$(ADDRESS)" + {{- include "zfslocalpv.zfsController.leaderElection" . | indent 12 }} + {{- range .Values.zfsController.resizer.extraArgs }} + - {{ tpl . $ | quote }} + {{- end }} + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.zfsController.resizer.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: + {{- toYaml .Values.zfsController.resources | nindent 12 }} + - name: {{ .Values.zfsController.snapshotter.name }} + image: "{{ .Values.zfsController.snapshotter.image.registry }}{{ .Values.zfsController.snapshotter.image.repository }}:{{ .Values.zfsController.snapshotter.image.tag }}" + imagePullPolicy: {{ .Values.zfsController.snapshotter.image.pullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + {{- include "zfslocalpv.zfsController.leaderElection" . | indent 12 }} + {{- range .Values.zfsController.snapshotter.extraArgs }} + - {{ tpl . $ | quote }} + {{- end }} + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: + {{- toYaml .Values.zfsController.resources | nindent 12 }} + - name: {{ .Values.zfsController.snapshotController.name }} + image: "{{ .Values.zfsController.snapshotController.image.registry }}{{ .Values.zfsController.snapshotController.image.repository }}:{{ .Values.zfsController.snapshotController.image.tag }}" + args: + - "--v=5" + {{- include "zfslocalpv.zfsController.leaderElection" . | indent 12 }} + {{- range .Values.zfsController.snapshotController.extraArgs }} + - {{ tpl . $ | quote }} + {{- end }} + imagePullPolicy: {{ .Values.zfsController.snapshotController.image.pullPolicy }} + resources: + {{- toYaml .Values.zfsController.resources | nindent 12 }} + - name: {{ .Values.zfsController.provisioner.name }} + image: "{{ .Values.zfsController.provisioner.image.registry }}{{ .Values.zfsController.provisioner.image.repository }}:{{ .Values.zfsController.provisioner.image.tag }}" + imagePullPolicy: {{ .Values.zfsController.provisioner.image.pullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--feature-gates=Topology=true" + - "--strict-topology" + - "--enable-capacity={{ .Values.feature.storageCapacity }}" + - "--extra-create-metadata=true" + - "--default-fstype=ext4" + {{- include "zfslocalpv.zfsController.leaderElection" . | indent 12 }} + {{- range .Values.zfsController.provisioner.extraArgs }} + - {{ tpl . $ | quote }} + {{- end }} + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: + {{- toYaml .Values.zfsController.resources | nindent 12 }} + - name: {{ .Values.zfsPlugin.name }} + image: "{{ .Values.zfsPlugin.image.registry }}{{ .Values.zfsPlugin.image.repository }}:{{ .Values.zfsPlugin.image.tag }}" + imagePullPolicy: {{ .Values.zfsPlugin.image.pullPolicy }} + env: + - name: OPENEBS_CONTROLLER_DRIVER + value: controller + - name: OPENEBS_CSI_ENDPOINT + value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: OPENEBS_IO_INSTALLER_TYPE + value: "{{ if (not (hasKey .Values.analytics "installerType")) }}zfs-localpv-helm{{ else }}{{ .Values.analytics.installerType }}{{ end }}" + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + {{- if .Values.analytics.gaId }} + - name: GA_ID + value: {{ .Values.analytics.gaId | quote }} + {{- end }} + {{- if .Values.analytics.gaKey }} + - name: GA_KEY + value: {{ .Values.analytics.gaKey | quote }} + {{- end }} + - name: OPENEBS_IO_ENABLE_BACKUP_GC + value: "{{ .Values.backupGC.enabled }}" + args : + - "--endpoint=$(OPENEBS_CSI_ENDPOINT)" + - "--plugin=$(OPENEBS_CONTROLLER_DRIVER)" + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: + {{- toYaml .Values.zfsController.resources | nindent 12 }} + volumes: + - name: socket-dir + emptyDir: {} +{{- if .Values.zfsController.additionalVolumes }} +{{- range $name, $config := .Values.zfsController.additionalVolumes }} + - name: {{ $name }} +{{- tpl (toYaml $config) $ | nindent 10 }} +{{- end }} +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.zfsController.nodeSelector }} + nodeSelector: +{{ toYaml .Values.zfsController.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.zfsController.securityContext }} + securityContext: +{{ toYaml .Values.zfsController.securityContext | indent 8 }} +{{- end }} +{{- if .Values.zfsController.tolerations }} + tolerations: +{{ toYaml .Values.zfsController.tolerations | indent 8 }} +{{- end }} diff --git a/charts/zfs-localpv/templates/zfs-node.yaml b/charts/zfs-localpv/templates/zfs-node.yaml new file mode 100644 index 0000000..8acc330 --- /dev/null +++ b/charts/zfs-localpv/templates/zfs-node.yaml @@ -0,0 +1,171 @@ +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ template "zfslocalpv.fullname" . }}-node + namespace: {{ .Release.Namespace }} + {{- with .Values.zfsNode.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "zfslocalpv.zfsNode.matchLabels" . | nindent 6 }} + updateStrategy: + rollingUpdate: + maxUnavailable: 100% + type: RollingUpdate + template: + metadata: + {{- with .Values.zfsNode.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 8 }} + {{- with .Values.zfsNode.podLabels}} + {{ toYaml . | nindent 8 }} + {{- end}} + {{- with .Values.loggingLabels}} + {{ toYaml . | nindent 8 }} + {{- end}} + spec: +{{- if .Values.zfsNode.priorityClass.create }} + priorityClassName: {{ template "zfslocalpv.zfsNode.priorityClassName" . }} +{{- end }} + serviceAccountName: {{ .Values.serviceAccount.zfsNode.name }} + hostNetwork: true +{{- if .Values.zfsNode.initContainers }} + initContainers: +{{- range $key, $value := .Values.zfsNode.initContainers }} + - name: {{ $key }} +{{ toYaml $value | indent 10 }} +{{- end }} +{{- end }} + containers: + - name: {{ .Values.zfsNode.driverRegistrar.name }} + image: "{{ .Values.zfsNode.driverRegistrar.image.registry }}{{ .Values.zfsNode.driverRegistrar.image.repository }}:{{ .Values.zfsNode.driverRegistrar.image.tag }}" + imagePullPolicy: {{ .Values.zfsNode.driverRegistrar.image.pullPolicy }} + args: + - "--v=5" + - "--csi-address=$(ADDRESS)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "rm -rf /registration/zfs-localpv /registration/zfs-localpv-reg.sock"] + env: + - name: ADDRESS + value: /plugin/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: {{ printf "%s%s" (include "zfslocalpv.zfsNode.kubeletDir" .) "plugins/zfs-localpv/csi.sock" | quote }} + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: NODE_DRIVER + value: openebs-zfs + volumeMounts: + - name: plugin-dir + mountPath: /plugin + - name: registration-dir + mountPath: /registration + resources: + {{- toYaml .Values.zfsNode.resources | nindent 12 }} + - name: {{ .Values.zfsPlugin.name }} + securityContext: + privileged: true + allowPrivilegeEscalation: true + image: "{{ .Values.zfsPlugin.image.registry }}{{ .Values.zfsPlugin.image.repository }}:{{ .Values.zfsPlugin.image.tag }}" + imagePullPolicy: {{ .Values.zfsPlugin.image.pullPolicy }} + args: + - "--nodename=$(OPENEBS_NODE_NAME)" + - "--endpoint=$(OPENEBS_CSI_ENDPOINT)" + - "--plugin=$(OPENEBS_NODE_DRIVER)" + env: + - name: OPENEBS_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OPENEBS_CSI_ENDPOINT + value: unix:///plugin/csi.sock + - name: OPENEBS_NODE_DRIVER + value: agent + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ALLOWED_TOPOLOGIES + value: "{{ .Values.zfsNode.allowedTopologyKeys }}" + volumeMounts: + - name: plugin-dir + mountPath: /plugin + - name: device-dir + mountPath: /dev + - name: encr-keys + mountPath: /home/keys + - name: chroot-zfs + mountPath: /sbin/zfs + subPath: zfs + - name: host-root + mountPath: /host + mountPropagation: "HostToContainer" + readOnly: true + - name: pods-mount-dir + mountPath: {{ include "zfslocalpv.zfsNode.kubeletDir" . | quote }} + # needed so that any mounts setup inside this container are + # propagated back to the host machine. + mountPropagation: "Bidirectional" + resources: + {{- toYaml .Values.zfsNode.resources | nindent 12 }} + volumes: + - name: device-dir + hostPath: + path: /dev + type: Directory + - name: encr-keys + hostPath: + path: {{ .Values.zfsNode.encrKeysDir }} + type: DirectoryOrCreate + - name: chroot-zfs + configMap: + defaultMode: 0555 + name: openebs-zfspv-bin + - name: host-root + hostPath: + path: / + type: Directory + - name: registration-dir + hostPath: + path: {{ printf "%s%s" (include "zfslocalpv.zfsNode.kubeletDir" .) "plugins_registry/" | quote }} + type: DirectoryOrCreate + - name: plugin-dir + hostPath: + path: {{ printf "%s%s" (include "zfslocalpv.zfsNode.kubeletDir" .) "plugins/zfs-localpv/" | quote }} + type: DirectoryOrCreate + - name: pods-mount-dir + hostPath: + path: {{ include "zfslocalpv.zfsNode.kubeletDir" . | quote }} + type: Directory +{{- if .Values.zfsNode.additionalVolumes }} +{{- range $name, $config := .Values.zfsNode.additionalVolumes }} + - name: {{ $name }} +{{- tpl (toYaml $config) $ | nindent 10 }} +{{- end }} +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.zfsNode.nodeSelector }} + nodeSelector: +{{ toYaml .Values.zfsNode.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.zfsNode.securityContext }} + securityContext: +{{ toYaml .Values.zfsNode.securityContext | indent 8 }} +{{- end }} +{{- if .Values.zfsNode.tolerations }} + tolerations: +{{ toYaml .Values.zfsNode.tolerations | indent 8 }} +{{- end }} diff --git a/charts/zfs-localpv/values.yaml b/charts/zfs-localpv/values.yaml new file mode 100644 index 0000000..36e0a86 --- /dev/null +++ b/charts/zfs-localpv/values.yaml @@ -0,0 +1,189 @@ +# Default values for openebs-zfslocalpv. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +imagePullSecrets: +# - name: "image-pull-secret" + +feature: + # enable storage capacity tracking feature + # Ref: https://kubernetes:io/docs/concepts/storage/storage-capacity + storageCapacity: true + +rbac: + # rbac.pspEnabled: `true` if PodSecurityPolicy resources should be created + pspEnabled: false + +loggingLabels: + openebs.io/logging: "true" + +# zfsNode contains the configurables for +# the zfs node daemonset +zfsNode: + componentName: openebs-zfs-node + driverRegistrar: + name: "csi-node-driver-registrar" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-node-driver-registrar + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v2.13.0 + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + # This can be configured to run on various different k8s distributions like + # microk8s where kubelet dir is different + kubeletDir: "/var/lib/kubelet/" + encrKeysDir: "/home/keys" + ## Labels to be added to openebs-zfs node pods + podLabels: {} + nodeSelector: {} + tolerations: [] + securityContext: {} + labels: {} + priorityClass: + create: true + name: zfs-csi-node-critical + # allowed topologykeys for csi driver + # The desired comma separated keys can be added here, + # by default all the node label keys are allowed. + # For example: + # allowedTopologyKeys: "kubernetes.io/hostname,openebs.io/rack" + allowedTopologyKeys: "All" + initContainers: {} + additionalVolumes: {} + +# zfsController contains the configurables for +# the zfs controller deployment +zfsController: + componentName: openebs-zfs-controller + initContainers: {} + additionalVolumes: {} + replicas: 1 + resizer: + name: "csi-resizer" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-resizer + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v1.13.2 + extraArgs: [] + snapshotter: + name: "csi-snapshotter" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-snapshotter + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v8.2.0 + extraArgs: [] + snapshotController: + name: "snapshot-controller" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/snapshot-controller + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v8.2.0 + extraArgs: [] + provisioner: + name: "csi-provisioner" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-provisioner + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v5.2.0 + extraArgs: [] + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + ## Labels to be added to openebs-zfs controller pods + podLabels: + name: openebs-zfs-controller + nodeSelector: {} + tolerations: [] + securityContext: {} + priorityClass: + create: true + name: zfs-csi-controller-critical + +# zfsPlugin is the common csi container used by the +# controller deployment and node daemonset +zfsPlugin: + name: "openebs-zfs-plugin" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: docker.io/ + repository: openebs/zfs-driver + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.9.0 +role: openebs-zfs + +serviceAccount: + zfsController: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-zfs-controller-sa + zfsNode: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-zfs-node-sa + +analytics: + enabled: true + installerType: "zfs-localpv-helm" + +backupGC: + enabled: false + +zfs: + # If you use a non-standard path to the zfs binary, specify it here + # bin: /run/current-system/sw/bin/zfs + bin: zfs + +crds: + zfsLocalPv: + # Install zfs-localpv CRDs + enabled: true + csi: + volumeSnapshots: + # Install Volume Snapshot CRDs + enabled: true + +# Allows adding helm specific labels to the components. +# Only useful for generating independent templates from helm. +enableHelmMetaLabels: true diff --git a/local_nvme_ephemeral_sc.yaml b/local_nvme_ephemeral_sc.yaml new file mode 100644 index 0000000..5c88db4 --- /dev/null +++ b/local_nvme_ephemeral_sc.yaml @@ -0,0 +1,13 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: local-nvme-ephemeral + annotations: + storageclass.kubernetes.io/is-default-class: "true" +provisioner: local.csi.openebs.io +parameters: + volgroup: vg_nvme_local + fstype: xfs +reclaimPolicy: Delete +volumeBindingMode: WaitForFirstConsumer +allowVolumeExpansion: true diff --git a/local_nvme_retain_sc.yaml b/local_nvme_retain_sc.yaml new file mode 100644 index 0000000..ad43d3c --- /dev/null +++ b/local_nvme_retain_sc.yaml @@ -0,0 +1,11 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: local-nvme-retain +provisioner: local.csi.openebs.io +parameters: + volgroup: vg_nvme_local + fstype: xfs +reclaimPolicy: Retain +volumeBindingMode: WaitForFirstConsumer +allowVolumeExpansion: true diff --git a/templates/NOTES.txt b/templates/NOTES.txt new file mode 100644 index 0000000..be64229 --- /dev/null +++ b/templates/NOTES.txt @@ -0,0 +1,16 @@ + +Successfully installed OpenEBS. + +Check the status by running: kubectl get pods -n {{ .Release.Namespace }} + +The default values will install both Local PV and Replicated PV. However, +the Replicated PV will require additional configuration to be fuctional. +The Local PV offers non-replicated local storage using 3 different storage +backends i.e Hostpath, LVM and ZFS, while the Replicated PV provides one replicated highly-available +storage backend i.e Mayastor. + +For more information, +- view the online documentation at https://openebs.io/docs +- connect with an active community on our Kubernetes slack channel. + - Sign up to Kubernetes slack: https://slack.k8s.io + - #openebs channel: https://kubernetes.slack.com/messages/openebs diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl new file mode 100644 index 0000000..a625408 --- /dev/null +++ b/templates/_helpers.tpl @@ -0,0 +1,93 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "openebs.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +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 "openebs.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "openebs.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "openebs.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "openebs.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + + +{{/* +Define meta labels for openebs components +*/}} +{{- define "openebs.common.metaLabels" -}} +chart: {{ template "openebs.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +{{- end -}} + +{{/* +Returns matched if the Hostpath Localpv Deployment is of v3.x +Usage: + {{- if include "hostpath_is_v3" . }} + Do something + {{- end }} +*/}} +{{- define "hostpath_is_v3" -}} + {{/* Name from https://github.com/openebs/charts/blob/openebs-3.10.0/charts/openebs/templates/localprovisioner/deployment-local-provisioner.yaml#L8 */}} + {{- $name1 := printf "%s-localpv-provisioner" (include "openebs.fullname" .) -}} + {{/* Name from https://github.com/openebs/dynamic-localpv-provisioner/blob/v4.3.0/deploy/helm/charts/templates/deployment.yaml#L5 */}} + {{- $sub := index .Subcharts "localpv-provisioner" -}} + {{- $name2 := include "localpv.fullname" $sub -}} + + {{/* Lookup Deployment by name1, fallback to name2 */}} + {{- $deploy := lookup "apps/v1" "Deployment" .Release.Namespace $name1 -}} + {{- if not $deploy -}} + {{- $deploy = lookup "apps/v1" "Deployment" .Release.Namespace $name2 -}} + {{- end -}} + + {{- if not $deploy -}} + {{/* There just is no localpv-provisioner deployment. This is unexpected. We err on the side of caution and match */}} + matched + {{- else -}} + {{/* Validate chart label matches v3.x.y */}} + {{- if and $deploy.metadata $deploy.metadata.labels -}} + {{- $chart := index $deploy.metadata.labels "chart" | default "" -}} + {{- if regexMatch "^(openebs|localpv-provisioner)-3\\.[0-9]+\\.[0-9]+.*$" $chart -}} + matched + {{- end -}} + {{- else -}} + {{/* + Localpv deployment exists, but doesn't have .metadata or .metadata.labels for some reason. + This may happen in a dry-run due to how lookup behaves. Erring on the side of caution and matching. + */}} + matched + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/templates/loki-storage/storage/localpv-storageclass.yaml b/templates/loki-storage/storage/localpv-storageclass.yaml new file mode 100644 index 0000000..857f6cc --- /dev/null +++ b/templates/loki-storage/storage/localpv-storageclass.yaml @@ -0,0 +1,33 @@ +{{- if and (.Values.loki.localpvScConfig.enabled) (.Values.loki.singleBinary.persistence.enabled) (.Values.loki.enabled) }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" + - name: BasePath + value: {{ tpl ( .Values.loki.localpvScConfig.loki.basePath | quote ) . }} + openebs.io/cas-type: local + name: {{ tpl .Values.loki.localpvScConfig.loki.name . | required "StorageClass name for loki localpv storage cannot be empty" }} +provisioner: openebs.io/local +reclaimPolicy: {{ .Values.loki.localpvScConfig.loki.reclaimPolicy }} +volumeBindingMode: {{ .Values.loki.localpvScConfig.loki.volumeBindingMode }} +{{- end }} +--- +{{- if and (.Values.loki.localpvScConfig.enabled) (.Values.loki.minio.persistence.enabled) (.Values.loki.enabled) }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" + - name: BasePath + value: {{ tpl ( .Values.loki.localpvScConfig.minio.basePath | quote ) . }} + openebs.io/cas-type: local + name: {{ tpl .Values.loki.localpvScConfig.minio.name . | required "StorageClass name for loki localpv storage cannot be empty" }} +provisioner: openebs.io/local +reclaimPolicy: {{ .Values.loki.localpvScConfig.minio.reclaimPolicy }} +volumeBindingMode: {{ .Values.loki.localpvScConfig.minio.volumeBindingMode }} +{{- end }} diff --git a/templates/pre-upgrade-hook.yaml b/templates/pre-upgrade-hook.yaml new file mode 100644 index 0000000..e94710d --- /dev/null +++ b/templates/pre-upgrade-hook.yaml @@ -0,0 +1,115 @@ +{{- if .Values.preUpgradeHook.enabled }} +{{- if .Release.IsUpgrade }} +{{- if include "hostpath_is_v3" . }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: openebs-pre-upgrade-hook + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-weight": "-2" + {{- with .Values.preUpgradeHook.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-pre-upgrade-hook + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-weight": "-2" + {{- with .Values.preUpgradeHook.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["get", "patch"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["delete", "list"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-pre-upgrade-hook + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-weight": "-1" + {{- with .Values.preUpgradeHook.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +subjects: +- kind: ServiceAccount + name: openebs-pre-upgrade-hook + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-pre-upgrade-hook + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: "openebs-pre-upgrade-hook" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-weight": "0" + {{- with .Values.preUpgradeHook.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + template: + metadata: + name: "openebs-pre-upgrade-hook" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + {{- with .Values.preUpgradeHook.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: "openebs-pre-upgrade-hook" + {{- with .Values.preUpgradeHook.tolerations }} + tolerations: + {{- toYaml . | nindent 6 }} + {{- end }} + restartPolicy: Never + containers: + - name: pre-upgrade-job + image: {{ .Values.preUpgradeHook.image.registry }}/{{ .Values.preUpgradeHook.image.repo }}:{{ .Values.preUpgradeHook.image.tag }} + imagePullPolicy: {{ .Values.preUpgradeHook.image.pullPolicy }} + command: + - "/bin/sh" + - "-c" + args: + - "(kubectl annotate --overwrite crd volumesnapshots.snapshot.storage.k8s.io volumesnapshotclasses.snapshot.storage.k8s.io volumesnapshotcontents.snapshot.storage.k8s.io helm.sh/resource-policy=keep || true) && (kubectl -n {{ .Release.Namespace }} delete deploy -l openebs.io/component-name=openebs-localpv-provisioner --ignore-not-found)" + {{- if .Values.preUpgradeHook.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.preUpgradeHook.imagePullSecrets | nindent 8 }} + {{- end }} +{{- end }} +{{- end }} +{{- end }}